home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / WATFAQ.ZIP / WATFAQ.TXT
Text File  |  1997-01-10  |  102KB  |  2,157 lines

  1.  
  2.  
  3.                The WATCOM C/C++ Programmer's FAQ
  4.  
  5.  
  6. WW        WW   AA   TTTTTTTT CCCC    OOOO      MM  MM    cccc   /
  7. WW        WW  AAAA     TT   CC  CC  OO  OO    MMMMMMMM  cc     /
  8. WW        WW AA  AA    TT  CC      OO    OO  MM MMMM MM  cccc /
  9.  WW      WW  AA  AA    TT  CC      OO    OO  MM  MM  MM      /
  10.  WW  WW  WW AA    AA   TT  CC      OO    OO MM   MM   MM    /
  11.  WW WWWW WW AAAAAAAA   TT  CC      OO    OO MM   MM   MM   / cccc   +   +
  12.   WWWWWWWW AA      AA  TT   CC  CC  OO  OO  MM   MM   MM    cc     +++ +++
  13.    WW  WW  AA      AA  TT    CCCC    OOOO   MM   MM   MM     cccc   +   +
  14.  
  15.                           Programmer's
  16.  
  17.                
  18.      FFFFFFFFFFFFFFFFFF      AAAAA               QQQQQQQQQQQQQQ
  19.      FFFFFFFFFFFFFFFFFF     AAAAAAA            QQQQQQQ     QQQQQQ
  20.      FFFFFF                AAAAAAAAA          QQQQQQ         QQQQQQ 
  21.      FFFFFF               AAAAAAAAAAA        QQQQQQQ         QQQQQQ 
  22.      FFFFFFFFFFFFFF      AAAAAA AAAAAA       QQQQQQQ         QQQQQQQ
  23.      FFFFFFFFFFFFFF     AAAAAA   AAAAAA      QQQQQQQ         QQQQQQQ
  24.      FFFFFF            AAAAAA     AAAAAA     QQQQQQQ     QQQ QQQQQQQ
  25.      FFFFFF           AAAAAAAAAAAAAAAAAAA     QQQQQQQ   QQQQQQQQQQQ 
  26.      FFFFFF          AAAAAAAAAAAAAAAAAAAAA     QQQQQQQQQQQQQQQQQQQ
  27.      FFFFFF         AAAAAA           AAAAAA       QQQQQQQQQQQQQQQQQQQQ 
  28.                                                                QQQQQQQQQQ
  29.  
  30. Written by Paul Hsieh
  31. qed@chromatic.com
  32. Revision 2.8
  33. August 4, 1996
  34.  
  35. (c) Copyright 1996, Paul Hsieh. All Rights Reserved.
  36. This document may be freely distributed in any format desired so long as
  37. the contents are not modified beyond non-obtrusive formatting.
  38.  
  39. Please note that although I've made a reasonable effort to verify the
  40. material contained in this FAQ, I make no guarrantees. The things written
  41. here are as true as I know them to be and should not be interpreted as
  42. anything more.  None of WATCOM, PowerSoft/Sybase or TenBerry systems or
  43. any other relevant company has officially endorsed this FAQ.  Furthermore,
  44. I have no affiliation with WATCOM, PowerSoft/Sybase or TenBerry systems.
  45.  
  46. WATCOM, PowerSoft, Sybase, TenBerry Systems, QNX, IBM, OS/2, Microsoft,
  47. Windows, Win32, Direct Draw, Direct X, Intel, Intel's RDX, Metaware,
  48. Symantec, Borland, CauseWay, Fastgraph, Varmint's Audio Tools, YackIcons,
  49. WordUp Graphics Toolkit, PC Magazine, Soft ICE, Phar lap, PModeW, Team 17
  50. etc., are copyrights/trademarks of their respective owners.
  51.  
  52. ---------------------------------------------------------------------------- 
  53.  
  54. Introduction
  55.  
  56. Many/most of the questions dealt with here assume that you already own a
  57. version of the WATCOM C/C++ compiler.  Ordering information is available
  58. on WATCOM's world wide web site.
  59.  
  60. As my personal strengths are in DOS coding, I have slanted this FAQ at 
  61. DOS programming using WATCOM C/C++.  If you are willing to contribute
  62. information regarding Windows, OS/2 programming or QNX programming please
  63. send it to me and I will include it.  Please note that I will only be able
  64. to easily verify DOS information (and Windows information, only with great
  65. difficulty.)
  66.  
  67. This FAQ mixes advocation with technical information.  It has been written
  68. this way because after years of posting on USENET this has become my
  69. natural style of writing.
  70.  
  71. ----------------------------------------------------------------------------
  72.  
  73. Frequently asked Questions
  74. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  75.  
  76. These are very commonly asked questions that people ask about WATCOM C/C++.
  77.  
  78. Q01. What is WATCOM C/C++?  What does WATCOM C/C++ come with?
  79. Q02. Where are WATCOM C/C++'s related web/ftp sites?
  80. Q03. Why is WATCOM C/C++ so popular?
  81. Q04. What's the syntax for ____?  How do I use the ____ tool?  How do I 
  82.      make the code generator do ____?  I just don't get it.
  83. Q05. I think there is a bug in the compiler, what should I do?
  84. Q06. Why do so many games use the DOS4GW.EXE DOS extender?
  85. Q07. What libraries are available for WATCOM C/C++?
  86. Q08. How do I program for Direct X using WATCOM C/C++?
  87. Q09. How do I program for Intel's RDX using WATCOM C/C++?
  88. Q10. Is the code WATCOM C/C++ produces the fastest/tightest?
  89. Q11. How do I use WATCOM's tools to help me optimize my code?
  90. Q12. How does WATCOM C/C++ compare with other C compilers?
  91. Q13. How do I debug DOS4GW apps under Windows 95?
  92. Q14. How do I debug WATCOM apps using Soft-ICE?
  93. Q15. How do I enable virtual memory for my DOS4GW application?  How do I 
  94.      know exactly what interrupts dos4gw handles all by itself?  How do I 
  95.      know exactly what a programmer have to do, using dos interrupts from 
  96.      protected mode?
  97. Q16. Why doesn't WATCOM use "_asm" for inline assembly like Microsoft and
  98.      Borland?  Afterall isn't that standard?
  99. Q17. Why does my code work only when I compile with debugging info on?
  100. Q18. What is FLAT memory model?  What is the advantage of a 32 bit
  101.      compiler such as WATCOM C/C++ over 16 bit compilers?  What are the
  102.      differences?  Will I be able to move my 16 bit DOS code straight over 
  103.      to 32 bit?
  104. Q19. I am getting this weird error message ...
  105. Q20. I am having malloc troubles.  It seems that I am trashing the heap 
  106.      but I don't know how to debug it.
  107. Q21. How do I write directly to graphics memory?
  108. Q22. How do I install a mouse event handler?
  109. Q23. What is DPMI and what role does it play in using WATCOM C/C++?  How
  110.      do I communicate between the 16 bit world and 32 bit world on my PC?
  111. Q24. What if I really need to compile a 16 bit model program?
  112. Q25. Why do WATCOM's results and Visual C++'s results differ on the same
  113.      source code?  Why does WATCOM implement the default signedness of
  114.      chars different from everyone else?  I am having difficulty porting
  115.      code to WATCOM C/C++.
  116. Q26. Can I link external assembly files together with my C files?
  117. Q27. How do #pragma's work?  How do I do inline assembly language?
  118. Q28. How do I do compiled bitmaps?  How do I do on-the-fly generated
  119.      code?
  120. Q29. How do I install a 32 bit interrupt vector?  How do I install a
  121.      bimodal interrupt?
  122. Q30. How do I get rid of the DOS4GW banner?  How do I bind DOS4GW.EXE to
  123.      my application?  How do I get rid of the external DOS4GW.EXE
  124.      altogether?  What other DOS extenders can I use?
  125. Q31. How do I make WATCOM C/C++ work with the latest OS/2 Toolkit?
  126. Q32. Are there any other WATCOM C/C++ caveats?
  127. Q33. Will WATCOM C/C++ support MMX?
  128. Q34. So what is your story?  Why did you do this?
  129.  
  130. Cool contributions
  131. ~~~~~~~~~~~~~~~~~~
  132.  
  133. These are contributions sent to me that do not correspond to a frequently
  134. asked question such as above, but which nevertheless are worth including.
  135.  
  136. C01. Profiling and debugging all rolled into one using an external
  137.      terminal connected by serial.  Contributed by Charlie Wallace.
  138. C02. Convert WATCOM's help file format to a text file for easier
  139.      reading and potentially for easier manipulation.
  140.  
  141. ----------------------------------------------------------------------------
  142.  
  143. Questions with answers
  144. ~~~~~~~~~~~~~~~~~~~~~~
  145.  
  146. Q01. What is WATCOM C/C++?  What does WATCOM C/C++ come with?
  147.  
  148. A01. WATCOM C/C++ is an Intel x86 based ANSI C++ and C compiler.  It
  149. supports various target operating systems.  Its most notable and exercised
  150. strength is its 32 bit DOS based support.  WATCOM has established its
  151. reputation as the makers of a world leading C compiler and has been in
  152. business for about 10 years.  You can get a more complete description of
  153. the compiler on the WATCOM web site, however here are the most notable
  154. things that are included:
  155.  
  156.   - 32 and 16 bit compilers, with standard libraries and DOS4GW.EXE.
  157.   - Additional DOS graphics and x86 specific libraries.
  158.   - Library manager and linker.
  159.   - All flavours of Windows programming including 16 and 32 bit MFC support
  160.     as well as Win32.  (Includes Windows SDK help.)
  161.   - Numerous Windows development tools (dialogue editors and so on.)
  162.   - Support for Dos extenders, OS/2, QNX, AutoCAD and Novell NLMs.
  163.   - IDE: Editor, Debugger, Execution Sampler/Profiler, Make, Touch.
  164.   - Online documentation and sample code.
  165.  
  166. ----------------------------------------------------------------------------
  167.  
  168. Q02. Where are WATCOM C/C++'s related web/ftp sites?
  169.  
  170. A02. These are the URLs that I am aware of:
  171.  
  172. WATCOM's home page
  173.     http://www.powersoft.com/products/languages/watccpl.html
  174. WATCOM C/C++ readmes
  175.     ftp://ftp.powersoft.com/pub/c_cpp/maintfls
  176. WATCOM C/C++ goodies
  177.     http://www.powersoft.com/services/files/c_gen.html
  178. KNUT's WATCOM C/C++ tutorial
  179.     http://www.oslonett.no/home/oruud/wat_tut.htm
  180. X2FTP site:
  181.     ftp://x2ftp.oulu.fi/pub/msdos/programming/watcom
  182. Official site for the WATCOM C/C++ FAQ
  183.     http://www.geocities.com/SiliconValley/9498/watfaq.txt
  184. FTP site for downloading the WATCOM C/C++ FAQ
  185.     ftp://x2ftp.oulu.fi/pub/msdos/programming/watcom/watfaq21.zip
  186. Previous WATCOM C/C++ FAQ
  187.     ftp://x2ftp.oulu.fi/pub/msdos/programming/watcom/watcom.07
  188. Miscellaneous WATCOM C/C++ and OS/2 device driver notes
  189.     http://www.wdi.co.uk/os2dd/QA__0009.htm
  190.  
  191. Email List server for WATCOM users
  192.     WATCOM-L@umdd.umd.edu 
  193.          send a message to listserv@umdd.umd.edu with the first line
  194.          of your message containing:
  195.          "SUBSCRIBE WATCOM-L John Doe" to subscribe.
  196.  
  197. USENET Newsgroups
  198.     news:alt.msdos.programmer
  199.     news:comp.os.msdos.programmer
  200.     news:rec.games.programmer
  201.  
  202. For tutorials on C/C++ (not specifically WATCOM) I have the following URLs:
  203.  
  204. C tutorials
  205.     http://www.strath.ac.uk/CC/Courses/NewCcourse/ccourse.html
  206.     http://www.iftech.com/classes/c/c0.htm
  207.     ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/teach-c.zip
  208. C++ tutorial
  209.     http://www.iftech.com/classes/cpp/cpp0.htm
  210.  
  211. ----------------------------------------------------------------------------
  212.  
  213. Q03. Why is WATCOM C/C++ so popular?
  214.  
  215. A03. WATCOM C/C++ is a very good tool.  It was the first pure 32 bit C/C++
  216. compiler widely available for x86 platforms.  It is a cross platform, high
  217. performance object code generator with no shortage of support tools.  It
  218. is on these merits that WATCOM has sustained its popularity.
  219.  
  220. Somewhere around 1992-93, WATCOM decided to drop the price (to a mere $400 
  221. Cdn vs. the old price of $1200 US) and started advertising more heavily in 
  222. magazines such as BYTE and PC Magazine.  Around this time I was heavily 
  223. advocating it (version 9.0) it in newsgroups such as "rec.games.programmer" 
  224. as the premiere C compiler for high performance and reliability, making such
  225. bold statements as: "WATCOM C/C++ will produce code which is at *least* 
  226. twice as fast as your current 16 bit compiler, and more typically around 
  227. five times as fast" which was not stretching the truth as far as I knew it. 
  228. Flame wars ensued where the focus was not only Borland and Microsoft, but 
  229. WATCOM.  
  230.  
  231. Then a single program was introduced that brought immediate and serious 
  232. attention to this compiler: DOOM.  What is this magical "DOS4GW" thing that 
  233. makes DOOM so good?  Were the DOOM programmers serious when they said they 
  234. used almost no assembly language?  What C compiler could they have possibly 
  235. used that could pump that much game onto the screen?  Soon, more and more
  236. games were made, hailing the telltale "DOS4GW" banner.  A few years later
  237. PC Magazine ran a comparative study of a collection of C compilers.  They
  238. hailed WATCOM C/C++ v9.5 for producing the fastest code (by a *wide* margin)
  239. but criticized it for its klunky command line driven interface.
  240.  
  241. Since then, many game companies switched and dozens of titles appeared
  242. with the "DOS4GW" banner displayed proudly including:  Raptor, System
  243. Shock, Descent, Magic Carpet, NASCAR Racing, Terminal Velocity etc.  32
  244. bit was finally becoming a reality on the PC, and it had nothing to do
  245. with "Windows" or "OS/2".  But even IBM was getting smart.  Numerous OS/2
  246. utilities and parts of the OS itself were compiled using WATCOM C/C++.
  247.  
  248. With version 10.0 WATCOM introduced an IDE, added support for MFC and
  249. added an assembler.  With 10.5 they decided to out source the new and
  250. improved IDE to an award winning third party developer, included better
  251. support for Win 95 and have built in a higher degree of Visual C++
  252. compatability.  With its licensing of MFC and ability to do ... well just
  253. about anything, WATCOM has clearly set its sights on one goal:  To become
  254. the defacto standard C/C++ compiler for PCs. Even Microsoft dares not
  255. ignore WATCOM C/C++; "Direct X" is compatible with WATCOM C/C++ (this was
  256. no doubt at the demand of the 3rd party BETA testers.)
  257.  
  258. ----------------------------------------------------------------------------
  259.  
  260. Q04. What's the syntax for ____?  How do I use the ____ tool?  How do I
  261. make the code generator do ____?  I just don't get it.
  262.  
  263. A04. The first place to look when trying to deal with general questions
  264. is the online help.  In a DOS box you can access the help via:
  265.  
  266. WHELP help_file [topic_name]
  267.  
  268. If you've installed the compiler to use the CDROM, be sure to have the
  269. WATCOM CDROM in the CDROM drive.  It takes a little digging but there is a
  270. lot of online information available.
  271.  
  272. If you give no parameters, most of the tools will respond with proper 
  273. command line syntax.
  274.  
  275. Additionally, the file %WATCOM%\DOS4GW.DOC gives you information on 
  276. configuring DOS4GW.EXE for certain systems and for using virtual memory
  277. under DOS.
  278.  
  279. Remember, that the WATCOM C/C++ compiler was not designed with beginners
  280. in mind.  If you are just starting to learn C/C++ then I is suggest you
  281. get plenty of reading on C/C++ in general and OS-specific programming
  282. manuals (I.e., DOS, Windows, OS/2, QNX, or whatever target platform you
  283. are interested in building for).  
  284.  
  285. For a deeper understanding of WATCOM C/C++ you'll need to learn at least
  286. bits and piece what object files, libraries, dll's, makefiles, and
  287. protected mode are.  Experienced programmers find that WATCOM C/C++
  288. doesn't have any real brick walls that other compilers have, but that
  289. coaxing it to do what you want it to do often takes some patience and
  290. perseverence.  That is the issue this FAQ is trying to address.
  291.  
  292. In general your pursuit of information when deal with difficulties using
  293. the WATCOM C/C++ compilers should be in the order of:  (1) Check the
  294. online help files, (2) Check reference materials such as a DOS or Windows
  295. programming books, as well as this FAQ, (3) Post a question to the
  296. internet (including the USENET newsgroups, or the WATCOM listserver listed
  297. above) (4) Contact WATCOM directly.
  298.  
  299. ----------------------------------------------------------------------------
  300.  
  301. Q05. I think there is a bug in the compiler, what should I do?
  302.  
  303. A05. You'd be surprised by the number of "compiler bugs" people think
  304. they've found.  Stop.  Take a deep breath and think about it for a moment.
  305. The WATCOM C/C++ compiler is generally a very stable tool.  Is your code
  306. proper ANSI C?  Are you violating the optimization assumptions assumed by
  307. your choice of compiler switches?  (Aliasing is the only one really at
  308. issue.)  Of the twenty or so "compiler bugs" that I thought I found, only
  309. two of them were ever even close to being real compiler bugs (see "Q32.
  310. Are there any other WATCOM C/C++ caveats?"  Numbers 3 and 6.)
  311.  
  312. The fact that something works on one compiler but not another is not
  313. necessarily an indication that one compiler is not functioning properly.
  314. For example, another compiler may not buffer writes to stdout via printf.
  315. So the fact that printf("Hello world"); echos immediately on one compiler
  316. and not at all on another (WATCOM C/C++ buffer's writes, so indeed its an
  317. example of a compiler that would not output anything) is not an indication
  318. that one or the other compiler is broken.
  319.  
  320. In general, you are supposed to call them and ask them for assistance, but
  321. these days, with their compiler being as popular as it is, it may be
  322. difficult to get satisfactory responses from their customer support.  You
  323. may first try your luck on the newsgroups listed at the top of this FAQ,
  324. if you have USENET access.
  325.  
  326. Powersoft/WATCOM themselves have set up a WWW bug report service on their 
  327. web page where you can submit problem reports.  In general, if they think
  328. your bug is nontrivial, then they will ask you to send them sample code
  329. which isolates the problem.  WATCOM provides a "shroud" utility that will
  330. obfusticate your code if you are worried about unwanted distribution of
  331. your sources.  It is available at the following URL:
  332.  
  333. ftp://ftp.powersoft.com/pub/c_cpp/general/shroud.zip
  334.  
  335. However, I would highly recommend that if feasible, you simply duplicate
  336. the problem in a clean project that does not expose any sources that you
  337. don't want exposed.
  338.  
  339. Calling them for assistance should be a last resort, but if you feel that
  340. you have found a genuine bug and have exhausted all reasonable avenues
  341. then you should not hesitate to tell them about it.  When and if they fix
  342. the problem, the compiler will be a better tool for all of us.
  343.  
  344. When there are bugs in the compiler that WATCOM is aware of and have
  345. fixed, they usually provide a patch that is available from their www and
  346. ftp sites (listed above.)
  347.  
  348. ----------------------------------------------------------------------------
  349.  
  350. Q06. Why do so many games use the DOS4GW.EXE DOS extender?
  351.  
  352. A06. DOS4GW.EXE is the royalty free redistributable 32 bit DOS extender
  353. that comes with WATCOM C/C++.  DOS4GW.EXE is made by "Tenberry Software"
  354. (formerly Rational Systems) specifically for WATCOM.  Although alternative
  355. DOS extenders with more/different features exist, users of WATCOM C/C++
  356. for DOS programming (that is to say, game programmers) will tend to use
  357. DOS4GW by default.  (It also has brand name recognition which may lead
  358. some programmers to desire the telltale DOS4GW banner.)
  359.  
  360. ----------------------------------------------------------------------------
  361.  
  362. Q07. What libraries are available for WATCOM C/C++?
  363.  
  364. A07. I don't have a comprehensive list, but I know that Varmint's Audio
  365. Tools, Fast Graph, YackIcons, WordUp Graphics Toolkit, ZSVGA, Microsoft's
  366. Direct X based Games SDK and Intel's RDX are notable libraries that come
  367. in WATCOM C/C++ friendly flavors.  In their latest versions, WATCOM has
  368. really gone out of their way to make themselves more compatible with
  369. Visual C++, which leads me to believe that many libraries out there which
  370. have been compiled for Visual C++ will also work with WATCOM C/C++.
  371. Needless to say there is no shortage of libraries out there that support
  372. WATCOM C/C++.  The WATCOM web site lists numerous 3rd party developers
  373. that are supporting their C/C++ compiler.
  374.  
  375. Here's a list of some stuff available for WATCOM C/C++:
  376.  
  377. Graphics libraries
  378.  
  379. WGT Watcom     ftp://x2ftp.oulu.fi/pub/msdos/programming/wgt51.zip 
  380. Xlib Watcom    ftp://x2ftp.oulu.fi/pub/msdos/programming/xlib/xlib06p2.zip 
  381. Watcom ModeX   ftp://x2ftp.oulu.fi/pub/msdos/programming/watcom/w_modex.zip
  382. JLIB           ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/jlib_1-5.zip
  383. Intel's RDX    http://www.intel.com/ial/rdx/
  384. Zephyr's ZSVGA http://www.phoenix.net/~balkum/products/zpmsvga.html
  385. gkit05b.zip    ftp://x2ftp.oulu.fi/pub/msdos/programming/watcom/gkit05b.zip
  386. 3DGPL          http://www.cs.mcgill.ca/~savs/3dgpl.html
  387.  
  388. Audio libraries
  389.  
  390. VAT Watcom     ftp://x2ftp.oulu.fi/pub/msdos/programming/mxlibs/vatpm061.zip 
  391. SMIX Watcom    ftp://x2ftp.oulu.fi/pub/msdos/programming/mxlibs/smixw125.zip 
  392. DSIK Watcom    ftp://x2ftp.oulu.fi/pub/msdos/programming/mxlibs/dsik205.zip 
  393.  
  394. ----------------------------------------------------------------------------
  395.  
  396. Q08. How do I program for Direct X using WATCOM C/C++?
  397.  
  398. A08  I am not a Windows programming expert but the following information
  399. appeared on the USENET:
  400.  
  401.   >How well does the Games SDK work with Watcom? If well, how many
  402.   >trials did it take to get the 'magic options' set up right?
  403.  
  404.   Works well, so far. I did have to use the windows.h file supplied with
  405.   the Games SDK, and that was hidden somewhere under the SAMPLES
  406.   subdirectory. I also had to define a couple of macros to get the samples
  407.   to compile. The whole thing took about 4 hours.
  408.  
  409. But then Ed Mueller said:
  410.  
  411.   With 10.6, you no longer need to include windows.h supplied with the 
  412.   Games SDK.  The macros you need to define are NOIME and NOMCX.
  413.  
  414. And Marty (mmallick@watcom.on.ca; hey! An employee of WATCOM!) said:
  415.  
  416.   In response to questions regarding the WATCOM C/C++ compiler and DirectX:
  417.  
  418.   Watcom C/C++ 10.6 and DirectX 2.0
  419.  
  420.   FYI:
  421.   The newly released DirectX 2.0 CD has a WATCOM directory that contains a
  422.   zip file that will make all of the necessary changes to the sample files
  423.   to work with Watcom C/C++ version 10.6.  Once these changes are made,
  424.   the makeallw.bat batch file can be run to make the sample programs.
  425.  
  426.   See the readme file in the WATCOM directory of the DirectX 2.0 CD for
  427.   more information.
  428.  
  429. "Avocado Green" (truongmn@UCUNIX.SAN.UC.EDU) wrote the following on the
  430. WATCOM List server:
  431.  
  432.   Here are some simple steps in using the Watcom IDE (10.6) to compile
  433.   and run the DirectDraw example (DDEX3) included with the DXSDK.  I
  434.   thought I'd save someone a few hours from messing with the make files.
  435.  
  436.   0.  Run the Watcom IDE (run it from the DOS box command line if it'd
  437.       make you feel less guilty.)
  438.  
  439.   1.  Select menu option "File->New Project"
  440.       Select the C:\DxSDK\Samples\DDex3 directory and enter
  441.       "ddex3.wpj" as your project name
  442.       Note:  If you installed the DirectX SDK in another directory
  443.              other than C:\DxSDK, make the changes as appropriate.
  444.  
  445.   2.  Enter "DDex3" as the target name,
  446.       "Win32" as Target Environment, and
  447.       "Windowed Executable [.exe]" as the Image Type.
  448.  
  449.   3.  Select menu option "Targets->Target Options->Windows Linking Switches"
  450.       Go to "2. Import, Export and Library Switches",
  451.       In field "Library directories(;):[libp]" enter "..\..\lib"
  452.       In field "Libraries(,):[libr]" enter "ddraw.lib"
  453.  
  454.   4.  Add these source files into your project:
  455.          ..\misc\ddutil.cpp
  456.          ddex3.cpp
  457.          ddex3.rc
  458.  
  459.   5.  Highlight the "ddex3.cpp" file and select menu option
  460.       "Sources->Sources Options->C++ Compiler Switches"
  461.       In field "Include directories:[-i]" add ";..\..\inc;..\misc;..\include"
  462.       so it should read
  463.  
  464.     "$(%watcom)\h;$(%watcom)\h\nt;..\..\inc;..\misc;..\include"
  465.  
  466.       ...of course you've set your Watcom environment variables already,
  467.       right?
  468.  
  469.   6.  Repeat step 5. for ddutil.cpp also, or you can perform step 5. on the
  470.       folder (.CPP) (representing all .CPP files)
  471.  
  472.   7.  Select menu option "Target->Make" and watch the few warning mesages
  473.       go by
  474.  
  475.   8.  Select menu option "Target->Run" and enjoy your Watcom compiler
  476.       running something other than "helloworld.c" (well, for me anyway)
  477.  
  478. Other Direct X specific FAQ's may best be answered at the following URL:
  479.  
  480.   http://www.microsoft.com/mediadev/msupport/mergfaq.htm#DirectDraw
  481.  
  482. ----------------------------------------------------------------------------
  483.  
  484. Q09. How do I program for Intel's RDX using WATCOM C/C++?
  485.  
  486. A09.  Intel's RDX is a library for composing sprites, playing back sound
  487. and video.  I don't know the details, however Hossain Morshed of Intel
  488. Corp. has responded to the inquiries of Ed Mueller and what appears to be
  489. the popularity of this FAQ with the following information:
  490.  
  491.   The following is a description of how RDX can be used with Watcom
  492.   compiler.
  493.   
  494.   Thanks,
  495.   Hossain Morshed
  496.   Intel Corp.
  497.  
  498.  
  499.                      Intel(R) RDX and Watcom* C/C++
  500.                                06/12/96
  501.   
  502.  
  503.   The RDX v2.1 Developer's Kit has been tested with Watcom C/C++ (v10.6).
  504.   It should be available for download this June (6/96) from the Intel RDX
  505.   Web Site (http://www.intel.com/ial/rdx/).
  506.   
  507.   If you are using Watcom C/C++ with the RDX v2.1 DLLs, you will need to
  508.   link your application to Watcom specific import libraries.  You can
  509.   create Watcom import libraries for the RDX DLLs by using the Watcom
  510.   WLIB tool.  For example, the following commands create the necessary
  511.   import libraries (provided that WLIB is in your path and the DLLs
  512.   reside in the C:\RDX\SYSTEM\RELEASE directory):
  513.   
  514.       wlib dmix.lib +c:\rdx\system\release\dmix.dll
  515.       wlib dinoav.lib +c:\rdx\system\release\dinoav.dll
  516.       wlib dino2d.lib +c:\rdx\system\release\dino2d.dll
  517.   
  518.   If you are trying to use Watcom C/C++ with the RDX v2.0 DLLs, we
  519.   suggest you use the RDX v2.1 Developer's Kit.  Besides providing many
  520.   new features and enhancements, it will also allow you to link your
  521.   applications successfully to the data structures that the DLLs export.
  522.   
  523.   However, if you want to use Watcom C/C++ with RDX v2.0, it is possible
  524.   to do this successfully by modifying the DINO.H and DINOAV.H header
  525.   files so that they declare the FX GUIDs using the DEFINE_GUID macro all
  526.   of the time and don't specify the DINO_SYMBOL/DINOAV_SYMBOL prefix.
  527.   Then all you have to do is modify one of your application's C or C++
  528.   modules to include the INITGUID.H header file before inclusion of
  529.   DINO.H and DINOAV.H.  This will cause the FX GUID data structures to be
  530.   declared in that module and thus be available to all of the other
  531.   modules in your application.
  532.   
  533.   Note:  To successfully compile the RDX v2.0 sample programs a similar
  534.   modification is necessary, in addition to a few other minor changes due
  535.   to differences in how Watcom C/C++ and Microsoft Visual C++* compile
  536.   source code.
  537.   
  538.   The RDX Developer's Kit does not provide Watcom specific make files for
  539.   the sample programs.
  540.   
  541.   
  542.   * Other product and corporate names may be trademarks of other
  543.     companies and are used only for explanation and to the owners'
  544.     benefit, without intent to infringe.
  545.  
  546. It appears that to use RDX, you must enter into an agreement with Intel
  547. that involve NDA's of some sort.  Refer to the URL given above for more
  548. information.
  549.  
  550. "Avocado Green" (truongmn@UCUNIX.SAN.UC.EDU) wrote the following on the
  551. WATCOM List server:
  552.  
  553.   Here are some simple steps in using the Watcom IDE (10.6) to compile
  554.   and run the Intel RDX 2.1 (2.0 did not work fully with Watcom)
  555.   example (EVENTS) included with the SDK.
  556.  
  557.   Note: The "lite" version of the RDX 2.1 SDK does not contain the
  558.         .bmp files needed to build the examples, so you'd probably
  559.         want to ask Intel for their RDX CD instead of downloading
  560.         the 63MB archive.
  561.  
  562.         I'm not sure if Intel has got v2.1 on CD yet, so if you have
  563.         v2.0, install that, then install the 2.1 "lite" version on top
  564.         of it.
  565.  
  566.   1.  Create the Watcom import library files by running wlib like so:
  567.  
  568.       - cd to \RDX\Lib (if you installed the SDK there)
  569.       - move the .lib files there to some other directory, you should
  570.         have nothing in \RDX\Lib
  571.       - run:
  572.       - wlib dmix.lib +c:\RDX\SYSTEM\RELEASE\dmix.dll
  573.       - wlib dinoav.lib +c:\RDX\SYSTEM\RELEASE\dinoav.dll
  574.       - wlib dino2d.lib +c:\RDX\SYSTEM\RELEASE\dino2d.dll
  575.       - wlib rdxam.lib +c:\RDX\SYSTEM\RELEASE\rdxam.dll
  576.  
  577.       There's a \RDX\SYSTEM\DEBUG directory with these same .DLL,
  578.       Guess these are the debuging version of the .DLLs
  579.  
  580.   2.  Run the Watcom IDE (run it from the DOS box command line if it'd
  581.       make you feel less guilty.)
  582.  
  583.   3.  Select menu option "File->New Project"
  584.       Select the C:\RDX\Samples\Events directory and enter
  585.       "Events.wpj" as your project name
  586.  
  587.   4.  Enter "Events" as the target name,
  588.       "Win32" as Target Environment, and
  589.       "Windowed Executable [.exe]" as the Image Type.
  590.  
  591.   5.  Select menu option "Targets->Target Options->Windows Linking
  592.   Switches"
  593.       Go to "2. Import, Export and Library Switches",
  594.       In field "Library directories(;):[libp]" enter "..\..\lib"
  595.       In field "Libraries(,):[libr]" enter "dmix.lib dino2d.lib"
  596.  
  597.   6.  Add these source files into your project:
  598.          events.c
  599.          help.c
  600.          winmain.c
  601.          events.rc
  602.  
  603.   7.  Highlight the folder (.C) (representing all .C files) and select
  604.   menu option
  605.       "Sources->Sources Options->C++ Compiler Switches"
  606.       In field "Include directories:[-i]" add ";..\..\include"
  607.       so it should read "$(%watcom)\h;$(%watcom)\h\nt;..\..\include"
  608.  
  609.   8.  Select menu option "Target->Make"
  610.       - wow not even a warning message.
  611.  
  612.   9.  Select menu option "Target->Run"
  613.       - Kill the dweebs
  614.  
  615. ----------------------------------------------------------------------------
  616.  
  617. Q10. Is the code WATCOM C/C++ produces the fastest/tightest?
  618.  
  619. A10. The WATCOM C/C++ compiler is generally regarded as among the best in
  620. terms of code generation.  For example, it produced significantly better
  621. code than any 16 bit compiler.  In an article in PC Magazine a few years
  622. back, benchmarks indicated WATCOM C/C++ version 9.5 had the tightest and
  623. fastest code among such compilers as Visual C++, Borland C/C++, Metaware
  624. Hi C, Zortech and Symantec (by a wide margin).  WATCOM's compilers have
  625. generally lead in the performance category in all brands and versions of
  626. their compilers starting with version 7.x, however among the more modern
  627. compilers it appears as though both "djgpp" and "Visual C++ 4.x" produce
  628. pure C code compilation which is as good (if not slightly better) than
  629. WATCOM's.
  630.  
  631. However, among the reasons for chosing WATCOM for high performance code
  632. generation is also its ability to use inline assembly language, the
  633. disassembly tool and its ability to collect accurate performance profiling
  634. information.  These tools are an indespensible part of the a "pedal to the
  635. metal" coder.
  636.  
  637. Be sure to follow the recommended switches for compiling your code that
  638. are given in the documentation.  Options such as "assume no aliasing" and
  639. using "reciprocal and multiply" for floating point divides can cause the 
  640. compiler to make assumptions about your code that have great performance
  641. impact even though the code generation techniques fall outside the rules 
  642. of the ANSI spec.  You should be sure you understand all the options for
  643. optimization.
  644.  
  645. ----------------------------------------------------------------------------
  646.  
  647. Q11. How do I use WATCOM's tools to help me optimize my code?
  648.  
  649. A11. WATCOM comes with 3 tools that make the code optimization process an
  650. easy one:  Execution sampler/profiler, disassembler and debugger.
  651.  
  652. There is a commonly held belief that in most applications 10% of your code
  653. will be executed 90% of the time.  That is to say, most applications tend
  654. to be bottlenecked, with the tightest bottleneck causing the greatest
  655. performance penalties.  With WATCOM C/C++ this still holds true, but not
  656. to such a severe extent, since WATCOM tends not to produce any "bottle-
  657. necky" code.
  658.  
  659. It is for this reason that your first step in your optimization phase
  660. should be to profile your code.  Even if your project is half complete,
  661. and not representative of its final form, execution sampling and profiling
  662. can often pinpoint unexpected bottlenecks in your code.
  663.  
  664. The execution sampler works by executing along with your code, randomly
  665. gathering instruction addresses during its run.  The profiler then converts
  666. the sample data into a chart which clearly shows what functions were
  667. called.  You can zoom into each function to see what lines of code are
  668. being executed, and keep doing that right down into assembly level.  To do
  669. this of course you have to compile your code with line number debugging
  670. information (/d1 or /d2.)
  671.  
  672. Not too surprisingly, data collected on Pentiums may show a sample data on
  673. machine instructions one after where the real execution occurred.  This is
  674. because the Pentium tries to execute instructions in pairs and the delays
  675. in one instruction may appear to be passed to the instruction it is paired
  676. with.
  677.  
  678. The other tool is the disassembler.  Using it you can see all the
  679. instructions compiled and correlate them their source lines.  WATCOM C/C++
  680. generally only uses 1 cycle instructions.  However, in order to strike a
  681. reasonable balance between code size and performance, WATCOM also uses some
  682. complex instructions.  The most notable being: mul, imul, div, idiv, movzx
  683. and movsx.  Simply scanning for these instructions can help you see where
  684. your data structures and type mismatching are causing sub-optimal code to
  685. be produced.
  686.  
  687. Finally the debugger is a simple tool not only for catching your bugs but
  688. for tracing through your code to see the path it is really taking.  Most
  689. of the time the execution path for small projects is fairly clear to the
  690. programmer.  But when multiple programmers are involved or your code
  691. becomes very fragmented, it is not so clear.  Very often, simply tracing
  692. through your programs can lead you into good insights about the
  693. performance of your program.
  694.  
  695. These general principles can be applied to any compiler, however few
  696. compilers can rival WATCOM in these tools.
  697.  
  698. For information about Pentium optimizations in general, Agner Fog has
  699. written up an excellent reference work which can be found on the following
  700. URL: http://www.geocities.com/SiliconValley/9498/p5opt.html
  701.  
  702. ----------------------------------------------------------------------------
  703.  
  704. Q12. How does WATCOM C/C++ compare with other C compilers?
  705.  
  706. A12. WATCOM C/C++'s biggest strengths right now are the performance tools
  707. and its ability to do cross-platform development.  With WATCOM the concept
  708. of a single project targetting multiple platforms is a practically
  709. realizable goal.  Their 32 bit compilers have been around since about
  710. 1992, years before Borland, or Microsoft had PC based 32 bit compiler
  711. technology (apparently DJGPP/DJGCC had it, but was highly obscure by
  712. comparison.)  However, their recent acquisition by PowerSoft has given
  713. them a highly acclaimed RAD tool (Optima++) that is based on top of the
  714. WATCOM C/C++ compiler; a joining of technologies that has caught their
  715. competitors with their pants down.
  716.  
  717. By comparison, Microsoft is currently only supporting VC++ which can
  718. create targets for Windows and DOS.  An extra dos extender (at extra cost)
  719. is required for 32 bit DOS code (I believe Pharlap's TNT is the only one
  720. really supported.)  DOS development is not supported by the IDE.  Version
  721. 4.x requires 24MB of memory to run smoothly (as opposed to WATCOM's
  722. requirement of 8MB.)  Microsoft has gotten into a habit of tweaking their
  723. compilers and operating systems in lock step; creating more and more
  724. conventions and odd things like "Thunking" (a Windows OS and VC++ specific
  725. way of performing 16<->32 bit execution segment translations.)  Users of
  726. Microsoft compilers (and products in general) become locked into their
  727. level of technology be it good or bad.  They also get locked into their
  728. "vision" as they are clearly pointing developpers to Windows 95 and
  729. Windows NT.  Of course OS/2, QNX and other platforms will never be
  730. supported.  The code generator for version 4.x compares favorably with
  731. WATCOM's, but the lack of reliable performance tools and the klunky
  732. out-dated method of inline assembly keeps VC++ from being the performance
  733. compiler of choice.
  734.  
  735. Borland is looking straight into the abyss these days.  I am not very
  736. familliar with their most recent products, but their strength has always
  737. been their IDE and compile speed.  But the latest WATCOM C/C++ compilers
  738. have closed these gaps considerably.  Borland attempted to diverge from
  739. MFC with "OWL".  They also stopped support for DOS for a brief period.
  740. Their PowerPak solution does not completely map in the first megabyte of
  741. memory which is problematic, and requires a lot of support to work around.
  742. Last I heard, Borland had dropped PowerPak support completely. These
  743. mistakes have cost Borland valuable time and their compiler technology has
  744. suffered as a result.  They themselves have practically admitted this and
  745. have thrown their efforts behind "Delphi" (a RAD tool layered on top of
  746. their non-standard Object Pascal.)
  747.  
  748. DJGPP beats all these compilers in two places:  code generation and price.
  749. (It appears to produce the tightest code, and costs $0.)  However, it
  750. falls flat on its face in terms of compile speed, interface and third
  751. party support.  DJGPP has only recently been robust enough to produce
  752. targets that work under both DOS and Windows DOS boxes, and the currently
  753. available Windows native 32 bit support is still in development stages
  754. (and is a separate compiler.)  The IDE is still in development and don't
  755. count on MFC support.  User support is there through the internet.
  756. Standard game libraries such as WGT, Fastgraph and Direct Draw have not
  757. been ported, and are not likely to ever be.  (On the other hand, SVGAKit
  758. from SciTech has been ported, very recently.)
  759.  
  760. I haven't heard so much as a peep from Metaware.  As for Symantec, I hear
  761. they are doing java.  Its likely that in the face of VC++ these companies
  762. felt they simply couldn't compete.  Indeed its hard to see how any other 
  763. compiler besides WATCOM C/C++ will survive Microsoft's latest product 
  764. juggernaut.
  765.  
  766. ----------------------------------------------------------------------------
  767.  
  768. Q13. How do I debug DOS4GW apps under Windows 95?
  769.  
  770. A13. WATCOM implements this using two DOS boxes.  This scheme allows the
  771. target program to retain full control of its VM without interference from
  772. the debugger (for, example, you should be able to debug apps which take
  773. over the screen without any problems besides Window's ability to
  774. virtualize that mode.)  So in theory, debugging should be more reliable.
  775. In one DOS box you run the windows server:
  776.  
  777. winserv -trap=rsi
  778.  
  779. and in the other you run the debugger:
  780.  
  781. wd -trap=win <executable name and arguements>
  782.  
  783. This is essentially the same procedure used for remote debugging over a
  784. serial cable.  Be sure that the [386enh] section of your system.ini
  785. contains the line "device=wdebug.386".  If you have problems try
  786. explicitely entering the path for wdebug.386 (it should be %WATCOM%\binw)
  787. and make sure that this file actually exists.  Be sure you are running
  788. wd.exe from the %watcom%\binw directory, not the %watcom%\binnt directory.
  789.  
  790. The "rsi" thing stands for "Rational Systems incorporated" which is the
  791. former name of TenBerry Systems, so don't be surprised if this changes to
  792. "tbs" in future versions of WATCOM C/C++.  For Windows NT, the server
  793. should be run as "vdmserv -trap=rsi" and the debugger should be run as "wd
  794. -trap=vdm <target command line>".  Similar solutions exist for other OS's
  795. (Thanks to Eric Kenslow, "Gothmog" and Tomas Likens for the majority of
  796. this information.)
  797.  
  798. ----------------------------------------------------------------------------
  799.  
  800. Q14. How do I debug WATCOM apps using Soft-ICE?
  801.  
  802. A14. Richard Horrocks writes:
  803.  
  804.   I don't know about 9.5, but for 10.0+ just compile with "-d3 -hc", link
  805.   with "debug codeview opt cvpack", then run DBG2MAP on the executable and
  806.   finally MSYM to get a symbol file that SoftIce can read (I can't verify
  807.   that this works with source line numbers as I get "out of memory load
  808.   source file" errors).
  809.  
  810. As far as I know, SOFT-ICE's symbol memory can be expanded by setting the
  811. 'SYM=###' in the *.DAT configuration file (in SOFT-ICE/W its the
  812. WINICE.DAT) Refer to the SOFT-ICE documentation for more information.
  813.  
  814. ----------------------------------------------------------------------------
  815.  
  816. Q15. How do I enable virtual memory for my DOS4GW application?  How do I
  817. know exactly what interrupts dos4gw handles all by itself?  How do I know
  818. exactly what a programmer have to do, using dos interrupts from protected
  819. mode?
  820.  
  821. A15. These and other DOS4GW specific questions are answered in the file
  822. %WATCOM%\DOS4GW.DOC, and in the online help under the DOS/4GW section of
  823. the user's guide.
  824.  
  825. ----------------------------------------------------------------------------
  826.  
  827. Q16. Why doesn't WATCOM use "_asm" for inline assembly like Microsoft and
  828. Borland?  Afterall isn't that standard?
  829.  
  830. A16.  Well, first off, that most definately is *not* standard (as in ISO
  831. or ANSI.)  Since the Microsoft/Borland _asm construct falls outside the
  832. ANSI standard, it promotes the generation of C sources which are not
  833. portable.  WATCOM instead uses the ANSI sanctioned "#pragma" directive.
  834. (See discussion latter for why WATCOM's method is intrinsically more
  835. portable than the _asm method.)  The file:
  836.  
  837. ftp://ftp.powersoft.com/pub/c_cpp/general/asm.txt
  838.  
  839. explains WATCOM's reasoning more fully.
  840.  
  841. ----------------------------------------------------------------------------
  842.  
  843. Q17. Why does my code work only when I compile with debugging info on?
  844.  
  845. A17. Dom Laflamme asked this question on the USENET newsgroup
  846. "rec.games.programmer" and I gave the following response:
  847.  
  848.   Dom Laflamme wrote:
  849.   > Hi,
  850.   > I've been coding a game engine for the passed 3 months.  It works 
  851.   > fine and it's fast.  Execept that when I turn the "Debugging Info" off
  852.   > in Watcom, _nothing_ works, it just crashes.  Since I cant debug the
  853.   > thing properly because of lack of debuging info, I face a truly
  854.   > problematic situation!
  855.  
  856.   There is a big difference in the code generated by using the /d2 debug
  857.   switch and no debugging.  /d1 is supposed to be nearly identical to
  858.   using no debugging but has significantly less deugging information.
  859.   WATCOM's optimizations are *NOT* broken as someone else posted.  But
  860.   they are truly aggressive.
  861.   
  862.   WATCOM recommends setting: /otexan, and each switch (t, e, x, a, and n)
  863.   is sufficiently documented in the online help.  I'm guessing that you
  864.   have these setting all on since "it's fast".  This recommendation is
  865.   based on the assumption that you are writing correct ANSI-C and that you
  866.   are not stepping outside the bounds to the point of breaking one of
  867.   WATCOM's optimization strategies.
  868.   
  869.   As a simple test, trying setting all the optimization switches off (as
  870.   well as the debugging switch off.)  If your engine starts working again,
  871.   then turn the optimization switches back on one at a time until your
  872.   engine breaks again.  Keeping in mind that the "a" switch (assume no
  873.   aliasing) is the only one in which correctly written (but really brain
  874.   dead) ANSI C can fail to execute.
  875.   
  876.   Once you have isolated the switch, read the documentation on the switch
  877.   very carefully.  Try to isolate the problem area and disassemble the
  878.   code with each optimization switch.  Once you see the difference, you
  879.   should be able to figure it out.
  880.   
  881.   You problem is likely one of three things:  (1) Simple mistake, like
  882.   dereferencing a bad pointer, or accessing outside the bounds of an
  883.   array, (2) You are misunderstanding the meaning of the "volatile" ANSI C
  884.   keyword and hence are misusing it, or not using it (the most likely)
  885.   when you should.  (3) You are aliasing pointers to non-disjoint
  886.   structures and WATCOM is reordering an inner loop in too aggressive a
  887.   manner (you will have to either recode or remove the "a" switch
  888.   entirely.)
  889.   
  890.   I have seen all three cases in my own work and in the work of others.  I
  891.   found that using WATCOM is an exercise in "re-learning" how ANSI C
  892.   really works.
  893.   
  894. ----------------------------------------------------------------------------
  895.  
  896. Q18.  What is FLAT memory model?  What is the advantage of a 32 bit
  897. compiler such as WATCOM C/C++ over 16 bit compilers?  What are the
  898. differences?  Will I be able to move my 16 bit DOS code straight over to
  899. 32 bit?
  900.  
  901. A18. WATCOM C/C++ can compile for either 16 bit or 32 bit.  The compilers
  902. are named wpp/wcc/wcl and wpp386/wcc386/wcl386 respectively for 16 bit 
  903. and 32 bit compiliation.  Every DOS programming model under the sun is
  904. implemented:  TINY, SMALL, COMPACT, MEDIUM, LARGE, HUGE (the 16 bit
  905. models) as well as FLAT and LARGE32 (the 32 bit models).
  906.  
  907. WATCOM C/C++'s default 32 bit DOS memory model is FLAT memory model.  FLAT
  908. memory model is an analogue of TINY model for 32 bit programs.  ES and DS
  909. are set to the same selector which points at the base of memory and maps
  910. all 4GB of address space.  CS is a selector that points to all of memory
  911. like DS and ES, but has the execution attribute set, meaning that it
  912. cannot be written to directly.  SS is set to a special stack segment to
  913. make stack overflow easier to detect.  This set up allows you to, in
  914. nearly all situtations, ignore segment/selector registers completely.  FS
  915. and GS are available for applications to use as they see fit and by
  916. default are set to 0.  (Hint:  Be sure to check the values of these
  917. selectors whenever you are debugging a failure in your code.  These
  918. selectors may change as a result of ill-behaved interrupt vector calls,
  919. and hence may need to be saved and restored properly (see the #pragma
  920. discussions elsewhere in this FAQ))
  921.  
  922. Unless you are dealing with interfacing to external 16 bit resources (such
  923. as APIs implemented through interrupts) you never need to deal with 64K
  924. segment limits, or strange keywords like FAR, NEAR or MK_FP.  Pointers and
  925. int's are both 32 bit, and while its not advisable, you can cast between
  926. the two and still be portable to most platforms (16 bit x86 environments
  927. and 64 bit DEC Alpha environments being the most notable exceptions.)
  928.  
  929. The extra bandwidth/precision you get for using a 32 bit coding model over
  930. a 16 bit one speaks for itself.  32 bit instructions executed from 32 bit
  931. segments do not need instruction overrides.  Beyond that only TINY and
  932. SMALL models (from the 16 bit model choices) compare with the low overhead
  933. for context switches.  That is to say, the only 16 bit models that also
  934. don't require selector loads for new data pointers or function calls are
  935. restricted to 64K of data and/or code.
  936.  
  937. Familliar DOS/BIOS data areas such as 0A000:0000 and 004f:0000 have been
  938. mapped in the most natural way:  16*segment+offset.  So VGA space is now
  939. at _FLAT:0x0A0000 and the standard BIOS area is now at _FLAT:0x04F0.  But
  940. this mapping doesn't necessarily hold true for the rest of system memory.
  941. This is actually a good thing since it allows for linearly mapped graphics
  942. cards to have their address range placed at a convenient place, namely the
  943. end of your conventional memory.  (Or in the case of Windows; usually a
  944. special address range with certain OS specific characteristics.)
  945.  
  946. (It is important to note that the construct MK_FP(0xA000,0); doesn't have
  947. the same meaning and will *NOT* correctly map the screen to a usable
  948. pointer.  Use (char *)(0x0A0000) as just described.)
  949.  
  950. This sudden ease of implmentation for everything is actually likely to
  951. make the job of porting from 16 bit DOS quite involved for many
  952. applications.  This porting procedure would mostly be an exercise in
  953. *undoing* all the 16 bit nonsense that was being done previously.
  954.  
  955. ----------------------------------------------------------------------------
  956.  
  957. Q19. I am getting this weird error message ...
  958.  
  959. A19. Lets go through some of the more common ones:
  960.  
  961. (1) When I run my program I get something like:
  962.  
  963.     DOS/4GW Protected Mode Run-time  Version 1.97
  964.     Copyright (c) Rational Systems, Inc. 1990-1994
  965.     DOS/4GW error (2001): exception 0Eh (page fault) at 237:825A401F
  966.     TSF32: prev_tsf32 5290
  967.     SS       23F DS       23F ES       23F FS         0 GS        87
  968.     EAX FFFFFFFF EBX 8244A380 ECX        0 EDX        0
  969.     ESI 824493A1 EDI 8244939C EBP 8244A374 ESP 8244A370
  970.     CS:IP  237:825A401F ID 0E COD        6 FLG    10202
  971.     CS=  237, USE32, page granular, limit FFFFFFFF, base        0, acc CFFB
  972.     SS=  23F, USE32, page granular, limit FFFFFFFF, base        0, acc CFF3
  973.     DS=  23F, USE32, page granular, limit FFFFFFFF, base        0, acc CFF3
  974.     ES=  23F, USE32, page granular, limit FFFFFFFF, base        0, acc CFF3
  975.     FS=    0, USE16, byte granular, limit        0, base        0, acc  0
  976.     GS=   87, USE16, byte granular, limit     FFFF, base    18DD0, acc F3
  977.     CR0: unavailable
  978.     Crash address (unrelocated) = 1:0000001F
  979.  
  980. This means that you have an error in your program.  If the address given
  981. in the last like looks like 1:000?????  (basically segment 1 and a
  982. reasonably small sized offset) then chances are you can run this under the
  983. debugger and have the address of your error shown to you.  If even the
  984. address looks like its off in the weeds, remember that WATCOM's debugger
  985. allows you to crawl up the execution stack to see how the crash was
  986. arrived at.
  987.  
  988. If running the debugger is out of the question or somehow problematic for
  989. you then you can generate a map file by putting "option map=myprog" on
  990. your link command line, or putting "/fm=myprog" on your wcl command line.
  991. This is most useful when you are compiling with debug info ("/d2" on your
  992. compile command line.)   The resulting myprog.map file is correlate the
  993. line numbers in your program to the "Crash address" given above.
  994.  
  995. Often the target address will be in a library function.  This generally
  996. means that either the parameters passed to the function are bogus, or some
  997. global state that the function depends on has become damaged.  Global
  998. state is hard to be debug, but not impossible.  See "Q20.  I am having
  999. malloc troubles.  It seems that I am trashing the heap but I don't know
  1000. how to debug it." later on in the FAQ.
  1001.  
  1002. But most of the time you are simply accessing memory you shouldn't be
  1003. (past end of an array, stuffing a pointer without first mallocing it,
  1004. inadvertantly corrupting a pointer that you use later.)  Remember,
  1005. pointers are not in "far" format, but rather in "_FLAT" format.  So
  1006. 0x0A0000000 is not the address of the VGA frame buffer, 0x0A0000 is.
  1007.  
  1008. (2) I type:
  1009.  
  1010.     wcl386 /l=dos4g hello.c
  1011.  
  1012. and get back:
  1013.  
  1014.     WATCOM Linker Version 10.6
  1015.     Copyright by WATCOM International Corp. 1985, 1996. All rights
  1016.     reserved.
  1017.     WATCOM is a trademark of WATCOM International Corp.
  1018.     Warning(1107): file __WCL__.LNK: line(2): undefined system name: dos4g
  1019.     loading object files
  1020.     searching libraries
  1021.     Error(3002): ** internal ** - format not decided
  1022.     Error: Linker returned a bad status
  1023.  
  1024. This means that when you installed WATCOM C/C++ you did not select 32-bit
  1025. DOS target.  You can run the installation procedure again to do an 
  1026. incremental install of 32 bit DOS compiler support.
  1027.  
  1028. (3) I'm using the IDE and am trying to compile an example program that comes
  1029. with "SupermundoGraph" and am getting messages like:
  1030.  
  1031.     wlink SYS dos op m op maxe=25 op q op symf @smg_ex1.lk1
  1032.     Warning(1028): smg_move_ is an undefined reference
  1033.     Warning(1028): smg_drawmap_ is an undefined reference
  1034.     file timmy.obj(C:\smg\src\smg_ex1.c): undefined symbol smg_resize_
  1035.     file timmy.obj(C:\smg\src\smg_ex1.c): undefined symbol smg_setclip_
  1036.  
  1037. "undefined reference" and "undefined symbol" indicate that something has
  1038. gone wrong in the linking process.  I am not very familiar with the IDEs
  1039. but, chances are you have not added in the SupermundoGraph library
  1040. properly.  According to the v10.0 IDE help documentation, you simply add
  1041. the library (*.lib) as if it were a source file.
  1042.  
  1043. Also watch that you have selected the right directories for your project.
  1044. I usually set up my directories and build my project sources before
  1045. invoking the IDE (in the rare occasions that I have ever used the IDE.)
  1046. If you are not careful, you will end up building projects right in the
  1047. compiler's own Windows tool directories, which makes for file maintenance
  1048. headaches sooner or later.
  1049.  
  1050. If that's not it, then perhaps the example is not compatible with your
  1051. version of WATCOM C/C++.  In this case, you should contact the library
  1052. vendor and inform them of this problem.
  1053.  
  1054. (4) I am getting linker errors from wpp386 that make no sense.  I have
  1055. everything externed and properly prototyped as far as I can tell.
  1056.  
  1057. On possibility is that you are trying to combine C and C++ code.  If it is
  1058. your intention to only write C, and not import C++ libraries, then you
  1059. should use the wcl386 or wcc386 compilers.  If you want to write C++ code,
  1060. you cannot simply mix C and C++ directly.  To import C code into a C++
  1061. project you must prototype them as extern "C" { } as follows:
  1062.  
  1063. extern "C" // c must be a capital C
  1064.         {
  1065.         extern void Set_320_200();
  1066.         extern void Put_Pixel( BYTE Color, WORD x, WORD y );
  1067.         }
  1068.  
  1069. The extern's publicize the symbol, and the "C" declares them as C symbols
  1070. so that they are linked without C++ attributions.  Thus they act as C
  1071. symbols, not C++ symbols.  This means their names are not mangled in the
  1072. objects, they cannot be overloaded, etc., etc.
  1073.  
  1074. Thanks to Lassche MA (mlassche@cs.vu.nl) for verifying this, and thanks to
  1075. Eric Kenslow for giving more a detailed explanation of extern "C".
  1076.  
  1077. ----------------------------------------------------------------------------
  1078.  
  1079. Q20. I am having malloc troubles.  It seems that I am trashing the heap
  1080. but I don't know how to debug it.
  1081.  
  1082. A20. Someone on rec.games.programmer asked this question and I gave this
  1083. as the response:
  1084.  
  1085.   Apparently somewhere in version 10.0 or 10.5, WATCOM had a problem with
  1086.   mallocing that has been fixed in a subsequent build.  It is likely that
  1087.   a patch for it exists on their WWW site.
  1088.  
  1089.   Nevertheless, I believe that bug was an extremely obscure one with the
  1090.   "free" command and is unlikely to be your problem.  Dealing with a
  1091.   trashed heap is difficult with any compiler, but WATCOM makes it
  1092.   particularly challenging because of its "frugal" heap memory tracking
  1093.   system.  If you do a little debugging/reverse engineering, you will see
  1094.   that a WATCOM memory allocation tracks the size in the int (signed long)
  1095.   just before the actual allocation itself.  So (ptr=(int*)malloc(99))[-1] 
  1096.   should be 99.  The malloc/free functions use this and this alone to
  1097.   track the heap so if you are trashing memory, especially these sizes,
  1098.   you will start dying really soon.
  1099.   
  1100.   I found that the WATCOM debugger is particularly good at tracking down
  1101.   precisely this sort of problem.  Allow me to tell you a story:
  1102.   
  1103.   Once upon a time I had a memory corruption in a large convoluted program
  1104.   I was writing.  So I started debugging by putting a wrapper around the
  1105.   "malloc" and "free" functions that added an additional size to test the
  1106.   validity of each malloced size against when I use it (which I put on the
  1107.   *other* side of the allocation.)  I put a test in the place where my
  1108.   program was accessing it and GP faulting.  I simply output a message
  1109.   indicating that the memory was trashed.  Using the debugger I put a
  1110.   break point on the error message printer.  Then I used the "reverse
  1111.   execution" feature to get me back to the failed memory size comparision
  1112.   and noted the machine address of the WATCOM size pointer.  Then I reset
  1113.   the program and put a breakpoint on access to that memory address.  It
  1114.   turns out that my program legally accessed it several times (on the
  1115.   order of a thousand.)  So I used the breakpoint "counter" to help me
  1116.   zero in (essentially a binary search) on the number many times this
  1117.   memory was accessed before the crash occurs.  By setting the counter
  1118.   appropriately, I found the code which was pounding on the size and
  1119.   rectified it.  Total time spent was about 1.5 hours which is not bad for
  1120.   a bug of this complexity (most of the time was spent on other desparate
  1121.   attempts to find the bug *before* diving in and trying the above
  1122.   procedure, which took < 10 mins.)
  1123.   
  1124.   I can't praise the WATCOM debugger enough for enabling me to do the
  1125.   above procedure.  In particular, the reverse execution feature gives me
  1126.   unparalleled power (with the exception of Soft-ICE, which of course,
  1127.   gives you much more power) for determining my context.  Mixed assembly
  1128.   and source level debugging allowed me to reverse engineer WATCOM's
  1129.   malloc method lickedy split.
  1130.  
  1131.   BTW, the bug in my program was simple.  I was accessing a pointer before
  1132.   mallocing it.
  1133.  
  1134. Paul Keys responded to the post above with a very good suggestion:
  1135.  
  1136.   Watcom has functions that can be used to debug the heap.  Functions such
  1137.   as _heapset, _heapchk, _heapwalk, are indespensible.  Using _heapset I
  1138.   have managed to find cases where I was using pointers to memory that had
  1139.   been mistakenly freed.  With _heapchk, I have tracked down where the
  1140.   heap lost its integrity.  And using _heapwalk, I was able to track down
  1141.   some rampant allocation that was slowly gobbling up all available
  1142.   memory.
  1143.  
  1144. Finally, it should be noted that on the WATCOM C/C++ file site there is a
  1145. sample program for diagnosing memory errors.  This program is located at the
  1146. following URL: ftp://ftp.powersoft.com/pub/watcom/c_gen/memcheck.zip
  1147.  
  1148. ----------------------------------------------------------------------------
  1149.  
  1150. Q21. How do I write directly to graphics memory?
  1151.  
  1152. A21. As mentioned above, the base of VGA memory is mapped at 0x0A0000.
  1153. The ports can be accessed via the outp() function, so even setting up Mode
  1154. X is no big deal.  For an example of this see:
  1155.  
  1156.     http://www.geocities.com/SiliconValley/9498/modex.zip
  1157.  
  1158. CGA and EGA are no more challenging than VGA.
  1159.  
  1160. SVGA modes have their own special problems.  The examples in Ferraro's
  1161. book on VGA's and SVGA's can be easily adapted to WATCOM C/C++, even in
  1162. pure C, with the exception of the VESA SVGA stuff.  Revision 1.2 of the
  1163. VESA SVGA interface (the interface most widely supported by SVGA's out
  1164. there) requires a 16 bit memory allocation for a data buffer and a 16 bit
  1165. call or interrupt to the "Bank Switch" procedure (my own investigations
  1166. lead me to find that the WinPtr call was not reliable on many graphics
  1167. cards and thus I stuck with the interrupt).  Many novices (including
  1168. myself, when I first tried it) make the mistake of thinking that they can
  1169. just pass in some appropriately cooked values into the required registers
  1170. as the VESA spec requires and just call int 10h.  Unfortunately this does
  1171. not work when the "es" register has to be stuffed with the segment for the
  1172. buffer that VESA fills in with mode info.  You need a protected mode to
  1173. real mode translation API to make dos allocations and simulate real mode
  1174. dos interrupts.  These are both achieved by using DPMI which is discussed
  1175. elsewhere in this FAQ (see Q23.)
  1176.  
  1177. Revision 2.0 of the VESA SVGA interface has a 32 bit interface and also
  1178. allows the option of mapping the entire frame buffer to a single
  1179. contiguous linear memory range.  The VESA SVGA specs are available at:
  1180.  
  1181. ftp://x2ftp.oulu.fi/pub/msdos/programming/specs/vesasp12.zip and
  1182. ftp://x2ftp.oulu.fi/pub/msdos/programming/specs/vbe20.zip
  1183.  
  1184. The WATCOM C/C++ file area also has an example URL for getting you started
  1185. using VESA:
  1186.  
  1187. ftp://ftp.powersoft.com/pub/c_cpp/general/newvesa.c
  1188.  
  1189. If you require linear memory access to SVGA, then your choices are:  (1) use
  1190. a VESA 2.0 interface (the easiest way), (2) Map in the graphics controller's
  1191. physical memory yourself (the hardest way), or (3) Use a more powerful DOS 
  1192. extender (than DOS4GW) that supports the DPMI phys to linear map function
  1193. (the expensive way, see next question for more information.)
  1194.  
  1195. Programming a graphics controller to use its specific functions requires
  1196. getting specifications for the graphics controller themselves.
  1197.  
  1198. ----------------------------------------------------------------------------
  1199.  
  1200. Q22. How do I install a mouse event handler?
  1201.  
  1202. A22. There is an example of this on the WATCOM C/C++ web site general file
  1203. page.  The URL is ftp://ftp.powersoft.com/pub/watcom/c_gen/tstmouse.c  The
  1204. general idea is just to make sure the declaration protocals have it taking
  1205. the right registers as its parameters, stack checking is turned off and DS
  1206. is reloaded.
  1207.  
  1208. ----------------------------------------------------------------------------
  1209.  
  1210. Q23. What is DPMI and what role does it play in using WATCOM C/C++?  How
  1211. do I communicate between the 16 bit world and 32 bit world on my PC?
  1212.  
  1213. A23. DPMI stands for "DOS Protected Mode Interface" and was dreamed up by
  1214. Intel and Microsoft.  It was a method for extending DOS's functionality
  1215. for supporting 32 bit programming at the lowest possible level.  Windows
  1216. is an example of a program which implements and leverages the DPMI
  1217. interface to enable "Enhanced Mode" and 32 bit DOS Extended applications
  1218. to run under DOS boxes.  (QDPMI, CWSDPMI and DOS4GW itself are other
  1219. examples.)
  1220.  
  1221. For most purposes DPMI essentially is an API for setting up 32 bit
  1222. selectors, and call gates between 16 and 32 bit execution segments.  A
  1223. version 0.90 (the one used by Windows) specification is available at:
  1224.  
  1225. ftp://x2ftp.oulu.fi/pub/msdos/programming/specs/dpmispec.arj
  1226.  
  1227. (you need 'ARJ' to decompress this file; its available elsewhere on x2ftp)
  1228. An online 1.0 specification can be found at:
  1229.  
  1230. ftp://x2ftp.oulu.fi/pub/msdos/programming/specs/dpmi100.zip
  1231.  
  1232. Also be sure to check the WATCOM C/C++ file area directory located at
  1233.  
  1234. ftp://ftp.powersoft.com/pub/watcom/c_gen
  1235.  
  1236. which has several relevant example files: rintcall.c, memory.c, and
  1237. dpmi800.c
  1238.  
  1239. The major differences between 0.90 and 1.0 is that 1.0 servers must return
  1240. with exact error codes in the event of a failure.  Among its most common
  1241. uses are:  allocating 16 bit memory and calling a 16 bit interrupt which
  1242. takes a 16 bit segmented address for a data buffer (ordinarily DOS4GW
  1243. and/or WATCOM's heap manager will not "malloc" from DOS memory, so it
  1244. essentially goes wasted.)  These are both required for supporting VESA
  1245. SVGA 1.2.  You may notice that among the many messages printed on DOOM's
  1246. fake "DOOM OS" init screen is a mention of DPMI allocations.  The
  1247. programmers at "id" probably wrote their own memory manager which uses
  1248. conventional memory in addition to regular heap memory.
  1249.  
  1250. The major short coming of DOS4GW is that its an incomplete implementation
  1251. of DPMI (0.90).  The WATCOM C/C++ users's guide describes what DPMI
  1252. functions *are* implemented in the "INTERRUPT 31H DPMI Functions" chapter.
  1253. DOS4GW even steps outside of the bounds in the sense that unsupported
  1254. functions do not simply return with the carry flag set indicating an error
  1255. (even though it has not completed the DPMI function.)  Forunately the
  1256. latest DOS4GW implements both the DOS alloc function and the simulated DOS
  1257. interrupt call, which are sufficient for setting up rudimentary 16 bit
  1258. communication.  If another DPMI manager is present, however, DOS4GW will
  1259. not set up its own DPMI server.  (I shelled out $150 for the CauseWay DOS
  1260. Extender which is far more robust and feature rich.)
  1261.  
  1262. So how does one actually coordinate 16 and 32 bit components together?
  1263. Allow me to explain one method.  All 32 bit DOS executables are bound with
  1264. a 16 bit kick-start program.  This kick-start program is, by default,
  1265. named WSTUB.EXE and is located in the %WATCOM%\BINB directory.  Obviously
  1266. you can change the contents of this file to anything you like (you can
  1267. probably do this without mucking with %WATCOM%\BINB\WSTUB.EXE directly,
  1268. but rather using the WBIND command, but I have not investigated this
  1269. fully.)
  1270.  
  1271. The 16 bit source code for WSTUB is also supplied, which makes the
  1272. kickstarting procedure fairly clear (starting with version 9.5, WATCOM
  1273. included both that 16 and 32 bit versions of their compiler in the same
  1274. package.)  It basically parses the command line arguments and passes
  1275. control to DOS4GW with itself as the first parameter followed by the rest
  1276. of the regular parameters.  You can write all your 16 bit components in
  1277. the stub, passing critical pointer values as command line parameters to
  1278. the 32 bit portion.  The pointers could point to anything, including 16
  1279. bit function entry point addresses and data areas.  The 32 portion would
  1280. do the simple math to convert the pointers and can pass control back to
  1281. the 16 bit stub functions using the DPMI 16 bit function call simulation
  1282. call.  Voila!
  1283.  
  1284. The reason I've described the above procedure is that I've seen others take
  1285. a less savory approach that I'd just as soon see avoided in the future.  In
  1286. at least one sound library I noticed that the implementer wrote a 16 bit
  1287. TSR that had to be executed beforehand.  Clearly, an unsanctioned or
  1288. unreliable method of communication between the 16bit TSR and 32bit library
  1289. was being used.  Using the stub method is much cleaner.
  1290.  
  1291. Why would you ever want to paste 16 and 32 bit code together?  Well, the
  1292. main reason would be that you have a large database of 16 bit code that is
  1293. most logically accessed as if coming from an interrupt event.  I've also
  1294. heard rumours to the effect that using DMA is a 16 bit only operation, but
  1295. I'd have to investigate that more fully before confirming it.
  1296.  
  1297. For example, you might have a substitute mouse driver written in 16 bit code
  1298. that you don't want to run as a separate TSR because you want to retain the
  1299. old mouse ISR.  So you could install it at the start of WSTUB, spawn the 32
  1300. bit process, then deinstall it when you come back.
  1301.  
  1302. Personally, I've modified WSTUB.EXE in minor ways, but in all honesty, I
  1303. have to admit that I have not tried the above procedure myself.
  1304. Nevertheless, I cannot see any other reason WATCOM would expose the 16 bit
  1305. source for WSTUB.EXE.  If somebody ever implements (or has already done
  1306. so) this idea successfully, I'd like to know about it.
  1307.  
  1308. ----------------------------------------------------------------------------
  1309.  
  1310. Q24. What if I really need to compile a 16 bit model program?
  1311.  
  1312. A24. Starting with version 9.5, WATCOM includes both the 16 and 32 bit
  1313. compilers in a single package.  The 16 bit compiler executables are
  1314. wpp.exe, wcl.exe and wcc.exe, while the 32 bit compilers are wpp386,
  1315. wcl386.exe and wcc386.exe.  It should just be a matter of changing your
  1316. makefile or flipping an IDE switch.
  1317.  
  1318. ----------------------------------------------------------------------------
  1319.  
  1320. Q25. Why do WATCOM's results and Visual C++'s results differ on the same
  1321. source code?  Why does WATCOM implement the default signedness of chars
  1322. different from everyone else?  I am having difficulty porting code to
  1323. WATCOM C/C++?
  1324.  
  1325. A25. A list of these differences can be found in the online help.  Here's
  1326. a list of the major gotcha's:
  1327.  
  1328. - To get around the signedness default be sure to pass a "/j" on the
  1329. command line.  
  1330.  
  1331. - WATCOM will, by default, use registers for its parameter passing
  1332. convention which makes it incompatible with regular COFF format libraries
  1333. and object files.  However, adding the extra declaration information via
  1334. "#pragma aux <function> frame;" will force WATCOM to pass parameters to
  1335. the function via the stack.  
  1336.  
  1337. - WATCOM's "wmake" utility parses a makefile format that is entirely
  1338. different from Microsoft's.  WATCOM decided to mimick UNIX as closely as
  1339. possible, while Microsoft went ahead and made their own standard.
  1340.  
  1341. - If you do asynchronous variable updates (such as modifying global
  1342. variables in an ISR), you *need* to declare your variable as "volatile".
  1343. Other C compilers optimization strategies act as if all variables were
  1344. declared volatile, and can mislead you into thinking it is unneccessary to
  1345. declare your variables this way.
  1346.  
  1347. - In general, WATCOM's C/C++ compilers tend to be more stable, however one
  1348. notable exception was the initial release of version 10.0.  But WATCOM had
  1349. patches available in a couple months which fixed its most outstanding
  1350. problems.  Relatively speaking, WATCOM's compiler is fairly robust and
  1351. more ANSI compliant than Visual C++ which can explain most discrepencies.
  1352.  
  1353. ----------------------------------------------------------------------------
  1354.  
  1355. Q26. Can I link external assembly files together with my C files?
  1356.  
  1357. A26. WATCOM's linker can accept .OBJ files in its own format or in the
  1358. standard intel format.  So using a separate assembler should not cause any
  1359. extra unneccessary complications.  Earlier versions (9.0) of the compiler
  1360. required the use of the "WOMP" utility to convert object formats.  Starting
  1361. with version 10.0, WATCOM C/C++ also comes with an external assembler called
  1362. "WASM".  However about the most praiseworthy comment I've heard about it was
  1363. something along the lines of "when I wrote everything from scratch and
  1364. followed all its rules, WASM seemed to be able to do the job."  Basically, I
  1365. don't believe WATCOM implemented many of the common, but superfluous
  1366. assembler features of MASM or TASM which a lot of people rely on and hence
  1367. were complaining about.
  1368.  
  1369. The most common problem when trying to link external assembly objects with
  1370. C/C++ objects is the name mangling/modification that the C/C++ compiler
  1371. does by default.  WATCOM C symbols in general are appended with an
  1372. undescore ("_"), whereas assembler names are not modified in any way.
  1373. This can be changed with a #pragma directive (see Q27, and the online
  1374. documentation for changing the symbol renaming convention used by WATCOM
  1375. C/C++.)  However, Eric Kenslow says that this is unneccesary.  WATCOM has
  1376. changed the meaning of "cdecl" recently, so how you deal with this may be
  1377. different depending on the version of WATCOM C/C++ you are using.
  1378.  
  1379. In any event, if you are having problems linking asm and C objects
  1380. together, use "wdisasm" (or simply a binary viewer for that matter) and
  1381. see how the shared symbol names are being modified for each of your
  1382. objects.  As recourse, in C you can use the #pragma name modification
  1383. directive, and in assembly you can simply append your public/extern names
  1384. with underscores as necessary.  Modifying your assembly symbol names is
  1385. the method Eric Kenslow recommends.
  1386.  
  1387. ----------------------------------------------------------------------------
  1388.  
  1389. Q27. How do #pragma's work?  How do I do inline assembly language?
  1390.  
  1391. A27. WATCOM's #pragma command is generally used as an alternative way for
  1392. defining C/C++ function generation properties.  Examples:
  1393.  
  1394. 1.  If you know that the parameters for a function are available either on
  1395. the stack or in certain x86 registers then you can assign which go where
  1396. *explicitely*.
  1397.  
  1398. 2.  If you know that at link time you will need the exported function
  1399. names to be mangled in some nondefault way then you can deal with that in
  1400. a #pragma.
  1401.  
  1402. 3.  If you want to generate inline assembly then you can do so as actual
  1403. assembly text or opcode bytes.  You give a function prototype and then
  1404. declare its content using the #pragma aux <function>="<asm>" directive.
  1405.  
  1406. This system for dealing with inline assembly is very powerful as it allows
  1407. you to explicitely declare your register usage, so that your C and
  1408. assembly stitch together perfectly.  Surprisingly, Visual C++ and
  1409. Borland's "_asm" method is not nearly as powerful.  With the "_asm" method
  1410. it is recommended that you look at the disassembly (you need to generate a
  1411. .COD file in Visual C++) of your surrounding source C to know what
  1412. registers are available to use, or simply do not modify any registers at
  1413. all.  This makes inline assembly coding tedious and difficult to maintain.
  1414.  
  1415. In contrast, the WATCOM method requires that you abstract your inline
  1416. assembly to have a regular C-function prototype which aids in portability
  1417. to non-x86 platforms.  A word of warning; inline assembly functions
  1418. declared with #pragma aux are not externed and hence behave like regular
  1419. C++ "inline" or "static" functions.  The typical method of dealing with
  1420. multiple C files using the same inline function is to define it in a local
  1421. include file common to your C files.  In this vein I think of #pragma's as
  1422. type checked macros, rather than functions.
  1423.  
  1424. Here's an example of the power of #pragma inline assembly for 32 bit FLAT
  1425. memory model.  Suppose we wish to implement the following:
  1426.  
  1427.   static void DWORDCopy(long *Source, long *Destination, int Length) 
  1428.   {
  1429.       for(;Length;Length--) 
  1430.       {
  1431.           *Source++=*Destination++;
  1432.       }
  1433.   }
  1434.  
  1435. in tight (i.e., small) assembly.  Using the WATCOM disassembly will show
  1436. you that the above is *not* compiled to a "rep movsd" no matter what
  1437. compiler settings you use.  The functionally equivalent inline pragma is
  1438. implemented as follows:
  1439.  
  1440.   void DWORDCopy(long *Source, long *Destination, int Length);
  1441.   #pragma aux DWORDCopy = " rep movsd " parm [ESI] [EDI] [ECX]\
  1442.   modify [ESI EDI ECX];
  1443.  
  1444. The above function will copy a packed array of 32 bit quantities from a
  1445. source pointer to a destination pointer using the "rep movsd" x86 assembly
  1446. construct.  The source and destination parameters are put into ESI and
  1447. EDI, with the length in ECX which is exactly what "rep movsd" requires for
  1448. priming.  In addition movsd requires that es and ds are set up, but that
  1449. is all take care of by the FLAT model start up code.  To implement this
  1450. same thing for Borland C++ or Visual C++ you need additional priming code
  1451. to transfer the source and destination parameters to the correct
  1452. registers.  Finally, the C-compiler needs to know what registers were
  1453. modified by the inline #pragma so that it can figure out what registers
  1454. are available to the surrounding C-code.  This cuts down on unnecessary
  1455. save and restores of registers that is generally required to safely
  1456. implement an inline "_asm".
  1457.  
  1458. Typically, the meat of the code appears in the double quotes, and is
  1459. several lines long, however opcodes can also be entered directly as bytes
  1460. as well.  Remember that ANSI C constants strings can be broken up in
  1461. sequence, and that lines can be stitched together with a "\" at the end.
  1462. #pragma's have to be declared on one line, so longer inline assembly
  1463. language sequences typically look more like:
  1464.  
  1465.   void SetMode13(void);
  1466.   #pragma aux SetMode13 =     \
  1467.   "    mov ax,13h    "    \
  1468.   "    int 10h        "    \
  1469.   modify [ax];
  1470.  
  1471. (My point above is that this #pragma statement is equivalent to:  
  1472. #pragma aux SetMode13 = " mov ax,13h int 10h " modify [ax];)  You then
  1473. call "SetMode13()" as if it were a regular function, and WATCOM does the
  1474. inline pasting for you.
  1475.  
  1476. Why would you ever want to enter opcodes?  Well, intel has a habit of
  1477. not documenting all of their mneumonics:
  1478.  
  1479.   unsigned int RDTSC(void *);
  1480.   #pragma aux RDTSC =   \
  1481.   0x0f 0x31 /* RDTSC */ \
  1482.   " mov [esi],eax   "   \
  1483.   " mov [esi+4],edx "   \
  1484.   parm [esi] modify [eax edx] value [eax];
  1485.  
  1486. (Although the WATCOM C/C++ compiler is actually aware of the rdtsc
  1487. instruction, it comes back with a error about the CPU setting when I try
  1488. to use it in inline assembly.  This is understandable given Intel's
  1489. unofficial status of this instruction.)  
  1490.  
  1491. Direct opcode inlining will become more important as people start using
  1492. Intel's "MMX" CPU extensions.
  1493.  
  1494. For more examples see "KNUT's WATCOM C/C++ tutorial" at
  1495.  
  1496.   http://www.oslonett.no/home/oruud/wat_tut.htm
  1497.  
  1498. The information given there is not 100% correct, however he gives detailed
  1499. examples that should give you a rough idea about how it works.  More
  1500. detailed information can be found in the online help.
  1501.  
  1502. ----------------------------------------------------------------------------
  1503.  
  1504. Q28. How do I do compiled bitmaps?  How do I do on-the-fly generated code?
  1505.  
  1506. A28. Its no big deal really.  Remember that CS, DS and ES are mapped to the
  1507. same physical space.  So in principle you need only malloc some space, fill 
  1508. it with 32 bit instructions (note that the opcodes between 16 and 32 bit do 
  1509. not translate directly) cast it to a function pointer (be especially careful 
  1510. with any parameters passed) and call it.
  1511.  
  1512. Modifying existing code (realizing of course that you take your life in
  1513. your own hands when you do this) is also possible.  Cast a function
  1514. pointer to a regular data pointer ((char *) is probably the only
  1515. appropriate pointer type) modify the data function code as if it were just
  1516. an array of opcodes and operands, then call the function.
  1517.  
  1518. Unfortunately, it looks like the compiler can do something really odd.  If
  1519. you assign the address of an existing function to a function pointer and
  1520. modify it directly under the same scope, the compiler will tack on a "CS:"
  1521. segment override, which will cause a page fault at execution time (Code
  1522. selectors cannot be used to write data.)  I don't quite see why they did 
  1523. this but the obvious work around of using another function to modify the 
  1524. actual code seems to work just fine:
  1525.  
  1526.   #include <stdio.h>
  1527.   #include <malloc.h>
  1528.   #include <stdarg.h>
  1529.  
  1530.   // printf compatible function prototype
  1531.   typedef int (* fntype)(char *, ... );
  1532.  
  1533.   char * fn;
  1534.  
  1535.   // Assembly language opcode to cause an immediate return:
  1536.   #define RET 0xc3
  1537.  
  1538.   void SetReturn(char * ptr) 
  1539.   {
  1540.           ptr[0] = RET;
  1541.   }
  1542.  
  1543.   void main(void) 
  1544.   {
  1545.           printf("Hello\n");        // Call "printf" as normal
  1546.           fn = (char *)malloc(128);    // Get some memory
  1547.           SetReturn(fn);        // Assign function
  1548.           ((fntype)fn)("Hello\n");    // Call function with parameter
  1549.           fn = (char *)&printf;        // Point to "printf"
  1550.           SetReturn(fn);        // Reassign printf function
  1551.           printf("Hello\n");        // Call "printf" as normal
  1552.   }
  1553.  
  1554. This was compiled with the -5r and -s switches (only.)  Clearly there is 
  1555. a difference between the stack based and non-stack based libraries which
  1556. makes this sort of self-modifying code particularly hazardous to deal
  1557. with.
  1558.  
  1559. The details for doing compiled bitmaps are beyond the scope of this FAQ,
  1560. however the general idea is to construct a number of 
  1561.  
  1562.   mov [edi+offset],immediate
  1563.  
  1564. one after the other which plot the sprite.  This makes transparency
  1565. encoding an intrinsic part of the sprite.  However, difficulty with
  1566. clipping (especially in the x direction) and destination memory write
  1567. alignment makes compiled sprites a questionable compromise to a more
  1568. general run length copy routine.  For more information read the newsgroup:
  1569. rec.games.programmer.
  1570.  
  1571. Doing more exotic things like writing your own compiler and setting up
  1572. your own compiler environment with protected execution spaces are beyond
  1573. the scope of this FAQ, but can probably be dealt with just using DPMI.
  1574.  
  1575. Now, before you go off and get any not so bright ideas, read the following
  1576. USENET conversation:
  1577.  
  1578.   > Hi there, I was wondering how you need to set things up so you can modify
  1579.   > your code and make copies of your functions under DOS4GW/Watcom....  I've
  1580.   > tried copying the function's code around to several different areas, but
  1581.   > it always gets a GPF....  Here's a simple example that crashes, if anyone
  1582.   > has any idea how to make it work, please let me know!  Thanks in advance!
  1583.   >
  1584.   > void printstuff()
  1585.   > {
  1586.   >     printf("HELLO\n");
  1587.   > }
  1588.   >
  1589.   > void main()
  1590.   > {
  1591.   >     void (*pFn)();
  1592.   >
  1593.   >     pFn = new char[500];
  1594.   >     memcpy( pFn, printstuff, 500 );
  1595.   >     pFn();
  1596.   > }
  1597.  
  1598.   The reason this doesn't work is because of the x86's relative addressing
  1599.   modes.  That is to say, that the >> printf("HELLO\n") << statement is
  1600.   translated to a *relative* call.  It gets translated to something like:
  1601.  
  1602.       mov eax,offset L1                     ; Pointer for string "HELLO\n"
  1603.       call relative ((offset printf)-($+5)) ; $ = current address.
  1604.  
  1605.   The x86 will automatically add in the current address to the relative
  1606.   offset and come back with the right address.  So in the copied version
  1607.   of the routine (in pFn()) you won't end up at the address of "printf"
  1608.   which you desire, because the relative difference was copied, rather
  1609.   than the physical address.
  1610.  
  1611.   There is no easy work around for this, and it is for reasons such as
  1612.   this that self-modifying code and related techniques, such as what
  1613.   you've tried to do are generally frowned upon.  The following two
  1614.   suggestions which fix the above program also serve to illustrate the
  1615.   flaw I am pointing out.
  1616.  
  1617.   (1) Instead of using 500, try using the number 31744 in both places.
  1618.  
  1619.   (2) Rather than calling printf directly, assign the address of printf
  1620.   to a global volatile (just to make sure WATCOM doesn't try any
  1621.   simplification tricks to avoid using it) function pointer, and call
  1622.   the function pointer instead of printf directly.
  1623.  
  1624. ----------------------------------------------------------------------------
  1625.  
  1626. Q29. How do I install a 32 bit interrupt vector?  How do I install a
  1627. bimodal interrupt?
  1628.  
  1629. A29. Look up _dos_getvect, _dos_setvect, _dos_keep and _chain_intr in the
  1630. online help.  I don't know much about bimodal interrupts but there is some
  1631. sample code in the WATCOM C/C++ general file area which demonstrates it.
  1632. The URL is ftp://ftp.powersoft.com/pub/watcom/c_gen/bimodal.zip.  I think
  1633. the idea is to write some assembly code which can be correctly executed
  1634. under either 16 or 32 bit segments and to make sure the interrupt vector
  1635. is hooked out without DOS4GW's interrupt code segment translation
  1636. intervening.
  1637.  
  1638. Here is an example for hooking out the timer interrupt.  Note the use of
  1639. "volatile" on the Timer_Tick variable declaration.  This is an often over
  1640. looked detail in this sort of asynchronous kind of programming.
  1641.  
  1642.   #include <dos.h>
  1643.   #include <stdio.h>
  1644.   #include <conio.h>
  1645.  
  1646.   volatile int Timer_Tick = 0;        /* Must be "volatile" */
  1647.  
  1648.   void __interrupt New_Timer_ISR(void);
  1649.   void (__interrupt * Old_Timer_ISR)(void);
  1650.  
  1651.   void __interrupt New_Timer_ISR(void)
  1652.   {
  1653.      Timer_Tick ++;
  1654.      Old_Timer_ISR();             /* Chain back to original interrupt */
  1655.   }
  1656.  
  1657.   /*  Ordinarily using INT 01Ch is the preferred method, but INT 08h can
  1658.    *  also be used.
  1659.    */
  1660.  
  1661.   #define TIMER_INTERRUPT (0x1C)
  1662.  
  1663.   void main(void)
  1664.   {
  1665.      Old_Timer_ISR = _dos_getvect( TIMER_INTERRUPT );
  1666.      _dos_setvect( TIMER_INTERRUPT, New_Timer_ISR );
  1667.  
  1668.      do
  1669.      {
  1670.         printf( "%d\n", Timer_Tick );
  1671.      } while( !kbhit() );
  1672.  
  1673.      _dos_setvect( TIMER_INTERRUPT, Old_Timer_ISR );
  1674.   }
  1675.  
  1676. If understanding is your goal then keep the following in mind:
  1677.  
  1678. - DOS4GW initializes most interrupt vectors to point into the extender
  1679. itself.  These new vectors are just a translation layer through DPMI to
  1680. switch into real mode and call the old vector.
  1681.  
  1682. - Since function pointers (including those declared as __interrupt) are
  1683. 32 bit offsets, the standard old DOS set/get vector int 21h functions will
  1684. not work in the standard old way.  Using _dos_getvect and _dos_setvect is
  1685. really the only reliable way to do ISR management.
  1686.  
  1687. - When a new 32 bit ISR is installed, no translation layer is installed
  1688. because it is not needed.
  1689.  
  1690. - DOS4GW emulates the old real mode interrupts as closely as possible by
  1691. preserving the regular register values across the interrupt translation
  1692. layer.  However, the segment registers are clearly not preserved.  This is
  1693. not only because a direct Selector->Segment translation makes no sense but
  1694. because CS, and SS, must be set up to simulate a 16 bit context.
  1695.  
  1696. - DOS4GW implements its own version of int 21h, which looks very much
  1697. like a 32 bit extension of int 21h.  This is why it is referred to as a
  1698. "DOS Extender".  In these cases places where there might be Selector->
  1699. Segment translation issues, there has been a work around to use the _FLAT
  1700. model paradigm.  See the online documentation for more information.
  1701.  
  1702. - When you are *required* to pass a segment value to a 16 bit interrupt
  1703. routine, you need to use the DPMI 300h "Simulated interrupt" function.
  1704.  
  1705. Other DOS extenders such as CauseWay and Pmode/w work in similar ways.
  1706.  
  1707. ----------------------------------------------------------------------------
  1708.  
  1709. Q30. How do I get rid of the DOS4GW banner?  How do I bind DOS4GW.EXE to
  1710. my application?  How do I get rid of the external DOS4GW.EXE altogether?
  1711. What other DOS extenders can I use?
  1712.  
  1713. A30. To get rid of the DOS4GW startup banner, bind your application to
  1714. "wstubq.exe" instead of the default "wstub.exe", or altertaively write
  1715. your own wstub.exe which does a "set DOS4GW=QUIET".
  1716.  
  1717. You cannot simply get rid of DOS4GW.EXE.  You need some sort of DOS
  1718. extender to drive your 32 bit app.  DOS4GW.EXE does not give you a link
  1719. option however other extenders such as DOS4G (the professional version of
  1720. DOS4GW), CauseWay, and PMODE (available at the x2ftp site) are plug in
  1721. DOS4GW compatible DOS extenders that will let you link the extender right
  1722. to your code.  This way, from the user perspective, your application is no
  1723. different from old 16 bit .exe's out there.  This is very important for
  1724. those interested in making tools that are easily transportable in a stand
  1725. alone form.
  1726.  
  1727. The other main advantage of using DOS Extenders *other* than DOS4GW, is
  1728. that all of them seem to support the DPMI "800" call, which is essential
  1729. for mapping physical memory to linear memory so that you can access all of
  1730. graphics memory for some SVGA cards directly.
  1731.  
  1732. WATCOM's 3rd party support home page includes other DOS extenders that
  1733. work with their compiler.  Pointers to these can all be found either
  1734. directly from a www search engine or on the WATCOM www page.  Here's a
  1735. quick comparision of what is out there that I am aware of.  If you have
  1736. information to add or about other extenders (such as blinker, DOS4G)
  1737. please tell me so I can include it.
  1738.  
  1739. Pharlap/TNT - Large proven API, which supersets DPMI.  The extender is
  1740. external and a separate link process is required, but WATCOM supports it
  1741. as part of the basic compiler environment.  I don't know the current going
  1742. rate, but last I checked it had a $500 price tag.
  1743.  
  1744. PModew/W v1.22 - Small, fast, links to exe, supports exe compression, plug
  1745. in compatible with DOS4GW and is free for development stages with a $500
  1746. flat charge if supplied with a shipping product.  It does not hook out
  1747. error exception routines which makes developping with it problematic at
  1748. best.  People who use it suggest developing with DOS4GW and adding in
  1749. pmodew later on.  For more information, check out http://www.di.net/pmw/
  1750.  
  1751. CauseWay - Fast, extended DPMI API, supports exe compression, links to
  1752. final exe, unlimited vitural memory, plug in compatible with DOS4GW, $200.
  1753. This is a real no nonsense dos extender which truly supersets DOS4GW
  1754. (error handling included, unlike pmodew) and which is at least as robust.
  1755. The WATCOM debugger can be used with uncompressed CauseWay extended apps
  1756. (be sure to follow the CauseWay installation instructions carefully), but
  1757. CauseWay comes with its own debugger that can deal with compressed apps as
  1758. well. It comes with an informative manual and plenty of sample code for
  1759. assembly and WATCOM C/C++ usage (including examples of using VESA SVGA.)
  1760. For more information, check out http://www.devoresoftware.com/
  1761.  
  1762. ----------------------------------------------------------------------------
  1763.  
  1764. Q31. How do I make WATCOM C/C++ work with the latest OS/2 Toolkit?
  1765.  
  1766. A31. I know nothing about WATCOM's OS/2 support, however Eric Lekven
  1767. (elekven@qualcomm.com) has given me the following information:
  1768.  
  1769.   WATCOM does not ship its compiler with the newest OS/2 Toolkit and must
  1770.   be obtained on the IBM OS/2 Developer Connection CDROM or direct from
  1771.   IBM.  Unfortunately both require payment, although there have been
  1772.   promotional versions of the Developer Connection CDROM shipped with Dr
  1773.   Dobb's Journal magazine which contain the Toolkit for free.  Perhaps
  1774.   they will do this again when OS/2 Merlin ships.
  1775.  
  1776.   In order to use IBM's OS/2 Warp Toolkit header files you need to edit
  1777.   three of the files.
  1778.  
  1779.     os2def.h:
  1780.        Find the two identical lines containing
  1781.        #if defined(__IBMC__) || defined(__IBMCPP__)
  1782.        Edit these two lines to contain this
  1783.        #if defined(__IBMC__) || defined(__IBMCPP__) || defined(__WATCOMC__)
  1784.  
  1785.     mmio.h, mmioos2.h:
  1786.        Both of these have two lists of #defines, one for country codes,
  1787.        the other for keyboard codes.  The values are decimal.  However
  1788.        these files are non-ANSI in that these decimal numbers have leading
  1789.        zeroes.  Delete the leading zeroes from all these #define
  1790.        statements.
  1791.  
  1792. Breckan Morris has verified this and recommends this over compiling with
  1793. the stack interface (/4s or /5s) which would also solve the problem.  He
  1794. also adds that there is also a line of the form:
  1795.  
  1796.   #if __IBMC__ || __IBMCPP__
  1797.  
  1798. which should be changed to
  1799.  
  1800.   #if __IBMC__ || __IBMCPP__ || __WATCOMC__
  1801.  
  1802. According to Vance Palodichuk, OS/2 4.0 (aka Merlin) has fixed the non-ANSI
  1803. leading zeros error from their mmio*.h files, and the modification listed by
  1804. Breckan above is sufficient.  I.e., you just have to add a "|| __WATCOMC__"
  1805. to one line of the os2def.h file to make it work.
  1806.  
  1807. It makes me wonder why IBM didn't simply add this modification themselves
  1808. just to make it that much easier to use the OS/2 toolkit.  This has to be
  1809. contrasted with Microsoft and Intel who have clearly gone out of their way
  1810. to support WATCOM C/C++.  It seems surprising to me that the relationship
  1811. between WATCOM and IBM isn't better since they have clearly been beneficial
  1812. to each other.
  1813.  
  1814. ----------------------------------------------------------------------------
  1815.  
  1816. Q32. Are there any other WATCOM C/C++ caveats?
  1817.  
  1818. A32. Here are some things I've learned while playing with WATCOM C/C++:
  1819.  
  1820. 1) Structure declarations that include shorts or chars are highly unlikely
  1821. to be in the physical order that they are declared.  This is because
  1822. WATCOM re-orders the entries for efficiency.  This is within ANSI C
  1823. specifications.  ANSI specs do require that the first entry of a structure
  1824. always be in the first position.  Hence, using structures of structures in
  1825. the right way, you can guarrentee the positioning of arbitrary structure
  1826. elements.
  1827.  
  1828. 2) ISR's do not properly load ES.  Hence you should insert a #pragma aux
  1829. macro (that looks something like: "push ds pop es") if you are using any
  1830. library functions.  Autoinitialization of arrays or structures is out of
  1831. the question, since WATCOM C/C++ uses rep movsd.
  1832.  
  1833. 3) To mix use of floating point in an ISR and in your main thread you must
  1834. save the floating point state (fsave? fstore?) at the beginning of your
  1835. ISR and restore it at the end (frestore?).  This is because the state of
  1836. the FPU cannot be reliably known when the ISR is executed (the stack may
  1837. be full because from the main thread).  Because saving and restoring the
  1838. FPU state is so costly, I would recommend against using the FPU entirely,
  1839. within ISRs.
  1840.  
  1841. 4) DOS4GW ISR's do not share the same stack with your main application.
  1842. This means that there are certain function calls that will not work:
  1843. longjmp and exit are the ones that immediately come to mind.  (Of course
  1844. any non-reentrant functions are off limits as well, but those are standard
  1845. ISR restrictions.)
  1846.  
  1847. 5) DOS4GW has no provisions for TSR programming, however it is possible
  1848. with the professional version, DOS4G.  (I am not aware of these
  1849. capabilities in other DOS extenders.)
  1850.  
  1851. 6) The #pragma aux inline assembly language directive is limited to
  1852. assembly sequences of up to 127 bytes or 255 bytes depending on the
  1853. version of the compiler.  WATCOM recommends using external assembly for
  1854. longer assembly sequences.  Charlie Wallace makes the good observation
  1855. that you can deal with this easily by breaking up your inline fragments
  1856. into pieces:
  1857.  
  1858.   void setup(void);
  1859.   #pragma aux setup =    \
  1860.   " mov edi,0xa0000 "    \
  1861.   " mov ecx,2000    "    \
  1862.   modify [edi ecx];
  1863.  
  1864.   void copy(void);
  1865.   #pragma aux copy =     \
  1866.   " loop1:          "    \
  1867.   " mov [edi],0     "    \
  1868.   " inc edi         "    \
  1869.   " dec ecx         "    \
  1870.   " jnz loop1       "    \
  1871.   modify [edi ecx];
  1872.  
  1873.   void main(void) 
  1874.   {
  1875.         setup();
  1876.         copy();
  1877.   }
  1878.  
  1879. The "modify" statements above are identical (the code generator is smart
  1880. enough to see that it doesn't need to restore then save the registers
  1881. between setup and copy), but as usual, they must describe the registers
  1882. modified in each inline #pragma.  If your flow logic is complicated in
  1883. such a way that you might jump from one #pragma to another, then you
  1884. should include all potentially modified registers for the collection of
  1885. #pragma's, in each #pragma's modify clause.
  1886.  
  1887. 7) Although mentioned elsewhere, I might as well reiterate that WATCOM has
  1888. by default implemented "char" as "unsigned char".  This can be overidden
  1889. with the /j switch, and the IDE does this by default.
  1890.  
  1891. 8) Apparently the WATCOM C/C++ compiler has difficulty on DOS systems with
  1892. 64MB of memory.  This problem does not occur with Windows DOS boxes.  The
  1893. solution, according to Charlie Wallace, is to replace w32run.exe (in
  1894. either %WATCOM%\binw or %WATCOM%\bin, depending on the which version you
  1895. are using) with one of tntrun.exe, d4grun.exe or x32run.exe (i.e., use the
  1896. copy command; if things screw up you can always quicky incrementally
  1897. reinstall from the CDROM.)  Apparently, the one which works is system
  1898. dependent.
  1899.  
  1900. 9) ES is assumed to be equal to DS and the direction flag is assumed
  1901. clear.  For autoinitialization, structure copying and many library
  1902. functions, WATCOM C/C++ simply uses the "rep movsd" assembly instruction
  1903. which means that the direction flag must be clear and ES, must be set to
  1904. the _FLAT selector, as they are by default.
  1905.  
  1906. WATCOM does not allow you to add (E)SP, (E)BP, or segment registers to a
  1907. "modify clause" in a #pragma.  So if they are modified (by a BIOS call, or
  1908. by some inline assembly) you have to save and restore those registers
  1909. yourself.  Similarly the direction flag should be explicitely cleared with
  1910. the "cld" instruction if it is modified.
  1911.  
  1912. ----------------------------------------------------------------------------
  1913.  
  1914. Q33. Will WATCOM C/C++ support MMX?
  1915.  
  1916. A33. Yes.  Intel made the following announcement in March 1996:
  1917.  
  1918.   "Powersoft Corporation has announced a commitment to deliver a version
  1919.   of Watcom C/C++ that supports Intel's new MMX(tm) technology. This
  1920.   support will enable development of lightning fast applications that
  1921.   exploit the capabilities of the MMX instruction set and that leverage
  1922.   the industry-leading optimization technology of Watcom C/C++. Watcom
  1923.   C/C++ will feature complete debugging support (including MMX technology
  1924.   register display and the disassembly of MMX instructions) as well as a
  1925.   functional interface from C/C++ that generates inline MMX instructions."
  1926.  
  1927. ----------------------------------------------------------------------------
  1928.  
  1929. Q34. So what is your story?  Why did you do this?
  1930.  
  1931. A34. I was a summer hire for WATCOM many eons ago, and I appreciate that
  1932. they gave me my first real job.  I have always been impressed by their
  1933. compilers and I've always wanted to see them crush both Borland and
  1934. Microsoft in the compiler arena.  (It looks like Borland will be laying
  1935. down for the count, but Microsoft is still there of course.)
  1936.  
  1937. WATCOM's most notable weakness is user support.  Their documentation is
  1938. very dry and generally does not fully explain all of the compiler's
  1939. capabilities.  I'm told this is the main reason a very high profile game
  1940. company stopped using their compiler in favour of another 32 bit DOS based
  1941. C compiler.  I've also found that lately, I'd been posting on a daily
  1942. basis just answering people's basic questions about WATCOM C/C++.  It is
  1943. in the hopes of curing this problem that I've written up this FAQ.
  1944.  
  1945. Finally, I am hoping that people make contributions and possibly submit
  1946. corrections so that I can verify my own knowledge.  This process also
  1947. results in a more reliable FAQ.  Numerous contributions have been made
  1948. thus far (including one from a WATCOM employee, and one from an Intel
  1949. employee representing Intel), and I have received a lot of positive
  1950. feedback which has made it worth while.
  1951.  
  1952. ----------------------------------------------------------------------------
  1953.  
  1954. Cool contributions
  1955. ~~~~~~~~~~~~~~~~~~
  1956.  
  1957. C01.  Profiling and debugging all rolled into one using an external
  1958. terminal connected by serial.  Contributed by Charlie Wallace.
  1959.  
  1960. [PH - The following contribution describes an alternative method for
  1961. profiling and debugging using a serial port connection to another
  1962. machine. I believe the idea is to redefine default the epilogue and
  1963. prologue code for your functions to communicate with a debugging or
  1964. profiling device.  The details were too complicated for me to verify.
  1965. However, for advanced WATCOM C/C++ users looking for an alternative
  1966. debugging or profiling method, the following may be useful.]
  1967.  
  1968. This is a small tip on using /ee /ep /en options of watcom, usually
  1969. these are used by the watcom profiler. I`ve found them useful for
  1970. debugging in the past, especially when you can`t load into the
  1971. debugger, like when watcom debugger had no support for X32,
  1972. what i`d do was compile with those options which adds a call
  1973. before and after every function call, so when the code locked
  1974. up i knew roughly where it was happening, i made the __PRO
  1975. routine emit the function name to the serial port at a
  1976. preset speed to a terminal, with a tab added at every level
  1977. entered, then the __EPI routine removed a tab and a new line
  1978. so on the serial terminal it looked thus :
  1979.  
  1980.         main(i)
  1981.                 my_func1(i)
  1982.                         my_func2(i)
  1983.                         my_func2(o)
  1984.                 my_func1(o)
  1985.         main(o)
  1986.  
  1987. where (i) and (o) are in and out, when the code locked up
  1988. only the last call entered would be displayed.
  1989.  
  1990. there are many other uses of this function, profiling with
  1991. other hardware, remember though this changes the execution
  1992. flow, you can compensate for it though, making a simple
  1993. debugger, debug options, watchdogs for memory leak and
  1994. code overwrites and so on . . .
  1995.  
  1996. However one caveat is to make sure you don`t add profile
  1997. hooks to the profiler code, write it in asm in a seperate
  1998. asm file, (don`t use #pragma aux), and don`t call
  1999. a C function of your own that has been compiled with /ep /en,
  2000. otherwise it`ll recurse.
  2001.  
  2002. a small example of how it works, assuming a simple compile
  2003. with wcl386 /ep /ee /en test.c pro.asm
  2004.  
  2005. where test.c is something like , simple..
  2006.  
  2007. int foo(int a)
  2008. {
  2009.         return a-1;
  2010. }
  2011.  
  2012. main()
  2013. {
  2014.         int a;
  2015.         a=foo(1);
  2016. }
  2017.  
  2018. which is compiled to
  2019.  
  2020.         db      'foo'
  2021.         db      3
  2022. _foo:
  2023.         push    ebp
  2024.         mov     ebp,esi
  2025.         call    __PRO
  2026.  
  2027.         ; does the function
  2028.  
  2029.         call    _EPI
  2030.         pop     ebp
  2031.         ret
  2032.  
  2033.         db      'main'
  2034.         db      4
  2035. _main:
  2036.         push    ebp
  2037.         mov     ebp,esi
  2038.         call    __PRO
  2039.  
  2040.         ; code goes here..
  2041.  
  2042.         call    _EPI
  2043.         pop     ebp
  2044.         ret
  2045.  
  2046. so get the function name, get the return address, esp will point to
  2047. it, subtract the length of the code before the __PRO call, ie the
  2048. push ebp + mov ebp,esi and add 1, use wdisasm to calculate this,
  2049. usually its 9, but i`m not saying it always will be, so check.
  2050. this byte is the length of the function name, subtract this from
  2051. the previous address just calculated and this gives you the
  2052. function name + length, ready to print out, or do whatever you
  2053. like..
  2054.  
  2055. Here is a 32bit version of __PRO and __EPI, for 32bit flat mode.
  2056.  
  2057. pro.asm - snip here 8-X
  2058.  
  2059. ;
  2060. ; use this fragment to code your own routines.
  2061. ;
  2062.         .586p
  2063.  
  2064.         .model flat
  2065.  
  2066.         .code
  2067.  
  2068.         PUBLIC __PRO
  2069.         PUBLIC __EPI
  2070.  
  2071. ; this routine gets called first
  2072. ;
  2073. ; usually like this, *- means subtract from current offset
  2074. ;
  2075. ;function_name:
  2076. ;               db      'my_c_function'
  2077. ;               db      *-function_name  (compute length of prev string)
  2078. ;my_c_function:
  2079. ;               push    ebp
  2080. ;               mov     ebp,esp
  2081. ;               call    __PRO
  2082. ;
  2083. ;
  2084.  
  2085. __PRO proc near
  2086.         push    esi
  2087.         push    eax
  2088.  
  2089.         mov     esi,[esp]
  2090.  
  2091.         sub     esi,9   ; this is the length of the
  2092.                         ; call __PRO+mov ebp,esp+push ebp+1
  2093.                         ; it may need to be changed to match different
  2094.                         ; compile options. check with wdisasm
  2095.  
  2096.         xor     eax,eax
  2097.         mov     byte ptr al,[esi]       ; length of function name
  2098.         sub     esi,eax
  2099.                                         ; esi -> function name
  2100.                                         ; eax -> length of string
  2101.  
  2102. ; do what you will with these, EXCEPT ! call any function in C
  2103. ; that you compiled with /ep or /en, otherwise it`ll recurse
  2104. ; for ever (at least for a while anyway).
  2105.  
  2106.         pop     eax
  2107.         pop     esi
  2108.         ret
  2109.  
  2110. __PRO endp
  2111.  
  2112. ; this gets called at the end of the function
  2113. ; usually like this :-
  2114. ;
  2115. ;       call    __EPI
  2116. ;       pop     ebp
  2117. ;       ret
  2118.  
  2119. __EPI proc near
  2120.  
  2121. ; do what you will here, just save all the reg's
  2122.         ret
  2123.  
  2124. __EPI endp
  2125.  
  2126.         end
  2127.  
  2128. pro.asm - snip here 8-X
  2129.  
  2130. ----------------------------------------------------------------------------
  2131.  
  2132. C02. Convert WATCOM's help file format to a text file for easier
  2133.      reading and potentially for easier manipulation.
  2134.  
  2135. Joergen Bech sent me a program which will convert WATCOM's .IHP files to
  2136. a text file, a table of contents file and an index file.  This will allow
  2137. you to peruse the file from your favourite text editor, or manipulate it
  2138. as you see fit.  The program is freely available at:
  2139.  
  2140.     http://www.geocities.com/SiliconValley/9498/ihp_conv.zip
  2141.  
  2142. It assumes you have DOS4GW.EXE at your disposal, in your path.
  2143.  
  2144. ----------------------------------------------------------------------------
  2145.  
  2146. Thanks for the feedback!
  2147. ========================
  2148.  
  2149. I have received numerous emails in response to my creation and public
  2150. dissemination of the WATCOM C/C++ FAQ.  They have, for the most part, been
  2151. very encouraging.  The contributions and corrections that have been sent
  2152. to me have served to increase the quality of the FAQ tremendously.
  2153. Readers can rest assure knowing that the accuracy and content is being
  2154. examined very carefully by discerning WATCOM C/C++ users.
  2155.  
  2156. I would like to especially thank WATCOM Systems and Intel corp. for their
  2157. invaluable individual